/// <summary> /// This variant of the intersection method returns the affected /// planes of the box if the box was hit. /// </summary> public bool Intersects( Box3d box, ref double tmin, ref double tmax, out Box.Flags tminFlags, out Box.Flags tmaxFlags ) { var dirFlags = DirFlags; tminFlags = Box.Flags.None; tmaxFlags = Box.Flags.None; if ((dirFlags & Vec.DirFlags.PositiveX) != 0) { { double t = (box.Max.X - Ray.Origin.X) * InvDir.X; if (t <= tmin) { return(false); } if (t < tmax) { tmax = t; tmaxFlags = Box.Flags.MaxX; } } { double t = (box.Min.X - Ray.Origin.X) * InvDir.X; if (t >= tmax) { return(false); } if (t > tmin) { tmin = t; tminFlags = Box.Flags.MinX; } } } else if ((dirFlags & Vec.DirFlags.NegativeX) != 0) { { double t = (box.Min.X - Ray.Origin.X) * InvDir.X; if (t <= tmin) { return(false); } if (t < tmax) { tmax = t; tmaxFlags = Box.Flags.MinX; } } { double t = (box.Max.X - Ray.Origin.X) * InvDir.X; if (t >= tmax) { return(false); } if (t > tmin) { tmin = t; tminFlags = Box.Flags.MaxX; } } } else // ray parallel to X-plane { if (Ray.Origin.X < box.Min.X || Ray.Origin.X > box.Max.X) { return(false); } } if ((dirFlags & Vec.DirFlags.PositiveY) != 0) { { double t = (box.Max.Y - Ray.Origin.Y) * InvDir.Y; if (t <= tmin) { return(false); } if (t < tmax) { tmax = t; tmaxFlags = Box.Flags.MaxY; } } { double t = (box.Min.Y - Ray.Origin.Y) * InvDir.Y; if (t >= tmax) { return(false); } if (t > tmin) { tmin = t; tminFlags = Box.Flags.MinY; } } } else if ((dirFlags & Vec.DirFlags.NegativeY) != 0) { { double t = (box.Min.Y - Ray.Origin.Y) * InvDir.Y; if (t <= tmin) { return(false); } if (t < tmax) { tmax = t; tmaxFlags = Box.Flags.MinY; } } { double t = (box.Max.Y - Ray.Origin.Y) * InvDir.Y; if (t >= tmax) { return(false); } if (t > tmin) { tmin = t; tminFlags = Box.Flags.MaxY; } } } else // ray parallel to Y-plane { if (Ray.Origin.Y < box.Min.Y || Ray.Origin.Y > box.Max.Y) { return(false); } } if ((dirFlags & Vec.DirFlags.PositiveZ) != 0) { { double t = (box.Max.Z - Ray.Origin.Z) * InvDir.Z; if (t <= tmin) { return(false); } if (t < tmax) { tmax = t; tmaxFlags = Box.Flags.MaxZ; } } { double t = (box.Min.Z - Ray.Origin.Z) * InvDir.Z; if (t >= tmax) { return(false); } if (t > tmin) { tmin = t; tminFlags = Box.Flags.MinZ; } } } else if ((dirFlags & Vec.DirFlags.NegativeZ) != 0) { { double t = (box.Min.Z - Ray.Origin.Z) * InvDir.Z; if (t <= tmin) { return(false); } if (t < tmax) { tmax = t; tmaxFlags = Box.Flags.MinZ; } } { double t = (box.Max.Z - Ray.Origin.Z) * InvDir.Z; if (t >= tmax) { return(false); } if (t > tmin) { tmin = t; tminFlags = Box.Flags.MaxZ; } } } else // ray parallel to Z-plane { if (Ray.Origin.Z < box.Min.Z || Ray.Origin.Z > box.Max.Z) { return(false); } } if (tmin > tmax) { return(false); } return(true); }
public static Sphere3d GetBoundingSphere3d(this Box3d box) => box.IsInvalid ? Sphere3d.Invalid : new Sphere3d(box.Center, 0.5 * box.Size.Length);
public Box3f(Box3d box) { Min = (V3f)box.Min; Max = (V3f)box.Max; }
public OrientedBox3d(Box3d box, Euclidean3d trafo) { Box = box; Trafo = trafo; }
public OrientedBox3d(Box3d box, Rot3d rot, V3d trans) { Box = box; Trafo = new Euclidean3d(rot, trans); }
public OrientedBox3d(Box3d box, Rot3d rot) { Box = box; Trafo = new Euclidean3d(rot, V3d.Zero); }
public static V3d UniformV3dFullClosed(this IRandomUniform rnd, Box3d box) { return(box.Lerp(rnd.UniformDoubleFullClosed(), rnd.UniformDoubleFullClosed(), rnd.UniformDoubleFullClosed())); }
public static V3d UniformV3dOpen(this IRandomUniform rnd, Box3d box) { return(box.Lerp(rnd.UniformDoubleOpen(), rnd.UniformDoubleOpen(), rnd.UniformDoubleOpen())); }
/// <summary> /// Gets outline corner indices of a box as seen from given position (in counter-clockwise order). /// Returns null if position is inside the box. /// </summary> public static int[] GetOutlineCornerIndicesCCW(this Box3d box, V3d fromPosition) { if (fromPosition.X < box.Min.X) { //-X if (fromPosition.Y < box.Min.Y) { //-Y if (fromPosition.Z < box.Min.Z) { // -X -Y -Z return(new[] { 1, 5, 4, 6, 2, 3 }); } else if (fromPosition.Z > box.Max.Z) { // -X -Y +Z return(new[] { 0, 1, 5, 7, 6, 2 }); } else { // -X -Y Z return(new[] { 1, 5, 6, 2 }); } } else if (fromPosition.Y > box.Max.Y) { // +Y if (fromPosition.Z < box.Min.Z) { // -X +Y -Z return(new[] { 0, 4, 6, 7, 3, 1 }); } else if (fromPosition.Z > box.Max.Z) { // -X +Y +Z return(new[] { 0, 4, 5, 7, 3, 2 }); } else { // -X +Y Z return(new[] { 0, 4, 7, 3 }); } } else { // Y if (fromPosition.Z < box.Min.Z) { // -X Y -Z return(new[] { 1, 4, 6, 3 }); } else if (fromPosition.Z > box.Max.Z) { // -X Y +Z return(new[] { 0, 5, 7, 2 }); } else { // -X Y Z return(new[] { 0, 4, 6, 2 }); } } } else if (fromPosition.X > box.Max.X) { // +X if (fromPosition.Y < box.Min.Y) { //-Y if (fromPosition.Z < box.Min.Z) { // +X -Y -Z return(new[] { 0, 2, 3, 7, 5, 4 }); } else if (fromPosition.Z > box.Max.Z) { // +X -Y +Z return(new[] { 0, 1, 3, 7, 6, 4 }); } else { // +X -Y Z return(new[] { 0, 3, 7, 4 }); } } else if (fromPosition.Y > box.Max.Y) { // +Y if (fromPosition.Z < box.Min.Z) { // +X +Y -Z return(new[] { 0, 2, 6, 7, 5, 1 }); } else if (fromPosition.Z > box.Max.Z) { // +X +Y +Z return(new[] { 1, 3, 2, 6, 4, 5 }); } else { // +X +Y Z return(new[] { 1, 2, 6, 5 }); } } else { // Y if (fromPosition.Z < box.Min.Z) { // +X Y -Z return(new[] { 0, 2, 7, 5 }); } else if (fromPosition.Z > box.Max.Z) { // +X Y +Z return(new[] { 1, 3, 6, 4 }); } else { // +X Y Z return(new[] { 1, 3, 7, 5 }); } } } else { // X if (fromPosition.Y < box.Min.Y) { //-Y if (fromPosition.Z < box.Min.Z) { // X -Y -Z return(new[] { 2, 3, 5, 4 }); } else if (fromPosition.Z > box.Max.Z) { // X -Y +Z return(new[] { 0, 1, 7, 6 }); } else { // X -Y Z return(new[] { 0, 1, 5, 4 }); } } else if (fromPosition.Y > box.Max.Y) { // +Y if (fromPosition.Z < box.Min.Z) { // X +Y -Z return(new[] { 0, 6, 7, 1 }); } else if (fromPosition.Z > box.Max.Z) { // X +Y +Z return(new[] { 2, 4, 5, 3 }); } else { // X +Y Z return(new[] { 2, 6, 7, 3 }); } } else { // Y if (fromPosition.Z < box.Min.Z) { // X Y -Z return(new[] { 0, 2, 3, 1 }); } else if (fromPosition.Z > box.Max.Z) { // X Y +Z return(new[] { 4, 5, 7, 6 }); } else { // X Y Z return(null); } } } }
/// <summary> /// Gets outline corners of a box as seen from given position (in clockwise order). /// Returns null if position is inside the box. /// </summary> public static V3d[] GetOutlineCornersCW(this Box3d box, V3d fromPosition) { var cs = box.ComputeCorners(); return(GetOutlineCornerIndicesCW(box, fromPosition)?.Map(i => cs[i])); }