Exemple #1
0
        /// <summary>
        /// Determines whether the specified bounding boxes intersect.
        /// </summary>
        /// <param name="boundingBox1">A bounding box.</param>
        /// <param name="boundingBox2">A bounding box.</param>
        /// <param name="intersection">Output variable for the intersection.</param>
        /// <returns>True if the <paramref name="boundingBox1"/> and the <paramref name="boundingBox2"/> intersect, otherwise false.</returns>
        public static bool BoundingBoxWithBoundingBox(BoundingBox boundingBox1, BoundingBox boundingBox2, out BoundingBox intersection)
        {
            var L = Math.Max(boundingBox1.Minimum.X, boundingBox2.Minimum.X);
            var R = Math.Min(boundingBox1.Maximum.X, boundingBox2.Maximum.X);
            var B = Math.Max(boundingBox1.Minimum.Y, boundingBox2.Minimum.Y);
            var T = Math.Min(boundingBox1.Maximum.Y, boundingBox2.Maximum.Y);
            var F = Math.Max(boundingBox1.Minimum.Z, boundingBox2.Minimum.Z);
            var N = Math.Min(boundingBox1.Maximum.Z, boundingBox2.Maximum.Z);

            if (R >= L && T >= B && F >= N)
            {
                intersection = new BoundingBox
                {
                    Minimum = new Vector3(L, B, N),
                    Maximum = new Vector3(R, T, F),
                };

                return true;
            }
            else
            {
                intersection = default(BoundingBox);
                return false;
            }
        }
Exemple #2
0
 /// <summary>
 /// Returns the distance between the specified bounding box and the specified line.
 /// </summary>
 /// <param name="boundingBox">A bounding box.</param>
 /// <param name="line">A line.</param>
 /// <returns>The distance between the <paramref name="boundingBox"/> and the <paramref name="line"/>.</returns>
 public static Number BoundingBoxToLine(BoundingBox boundingBox, Line line)
 {
     var center = (boundingBox.Minimum + boundingBox.Maximum) / 2;
     var position = Project.PointOnLine(center, line);
     var normal = Vector3.Normalize(center - position);
     return Distance.BoundingBoxToPlane(boundingBox, new Plane(normal, position));
 }
Exemple #3
0
 /// <summary>
 /// Returns the distance between the specified bounding boxes.
 /// </summary>
 /// <param name="boundingBox1">A bounding box.</param>
 /// <param name="boundingBox2">A bounding box.</param>
 /// <returns>The distance between the <paramref name="boundingBox1"/> and the <paramref name="boundingBox2"/>.</returns>
 public static Number BoundingBoxToBoundingBox(BoundingBox boundingBox1, BoundingBox boundingBox2)
 {
     var center = (boundingBox1.Minimum + boundingBox1.Maximum) / 2;
     var closestPoint1 = Vector3.Clamp(center, boundingBox2.Minimum, boundingBox2.Maximum);
     var closestPoint2 = Vector3.Clamp(closestPoint1, boundingBox1.Minimum, boundingBox1.Maximum);
     return Distance.PointToPoint(closestPoint1, closestPoint2);
 }
Exemple #4
0
        /// <summary>
        /// Determines whether the specified bounding boxes intersect.
        /// </summary>
        /// <param name="boundingBox1">A bounding box.</param>
        /// <param name="boundingBox2">A bounding box.</param>
        /// <returns>True if the <paramref name="boundingBox1"/> and the <paramref name="boundingBox2"/> intersect, otherwise false.</returns>
        public static bool BoundingBoxWithBoundingBox(BoundingBox boundingBox1, BoundingBox boundingBox2)
        {
            var L = Math.Max(boundingBox1.Minimum.X, boundingBox2.Minimum.X);
            var R = Math.Min(boundingBox1.Maximum.X, boundingBox2.Maximum.X);
            var B = Math.Max(boundingBox1.Minimum.Y, boundingBox2.Minimum.Y);
            var T = Math.Min(boundingBox1.Maximum.Y, boundingBox2.Maximum.Y);
            var F = Math.Max(boundingBox1.Minimum.Z, boundingBox2.Minimum.Z);
            var N = Math.Min(boundingBox1.Maximum.Z, boundingBox2.Maximum.Z);

            return R >= L && T >= B && F >= N;
        }
Exemple #5
0
 /// <summary>
 /// Initializes a new instance of the struct.
 /// </summary>
 /// <param name="boundingBox">Bounding box to copy.</param>
 public BoundingBox(BoundingBox boundingBox)
 {
     this.Minimum = boundingBox.Minimum;
     this.Maximum = boundingBox.Maximum;
 }
Exemple #6
0
 /// <summary>
 /// Determines whether the current bounding box is equal to the specified bounding box.
 /// </summary>
 /// <param name="value">A bounding box.</param>
 /// <returns>True if the current bounding box is equal to the <paramref name="value"/>, otherwise false.</returns>
 public bool Equals(BoundingBox value)
 {
     return
         this.Minimum == value.Minimum &&
         this.Maximum == value.Maximum;
 }
Exemple #7
0
        /// <summary>
        /// Attempts to parse the bounding box from the specified string.
        /// </summary>
        /// <param name="value">The string to parse.</param>
        /// <param name="numberStyle">The number style for each component.</param>
        /// <param name="formatProvider">The format provider for each component.</param>
        /// <param name="result">The output variable for the bounding box parsed from the <paramref name="value"/>.</param>
        /// <returns>True if the <paramref name="value"/> was parsed successfully, otherwise false.</returns>
        public static bool TryParse(string value, NumberStyles numberStyle, IFormatProvider formatProvider, out BoundingBox result)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            var numbers = Float.Parse(value, numberStyle, formatProvider);

            if (numbers.Length == ValueCount)
            {
                result.Minimum.X = numbers[0];
                result.Minimum.Y = numbers[1];
                result.Minimum.Z = numbers[2];
                result.Maximum.X = numbers[3];
                result.Maximum.Y = numbers[4];
                result.Maximum.Z = numbers[5];
                return true;
            }
            else
            {
                result = default(BoundingBox);
                return false;
            }
        }
Exemple #8
0
        /// <summary>
        /// Returns the distance between the specified bounding box and the specified ray.
        /// </summary>
        /// <param name="boundingBox">A bounding box.</param>
        /// <param name="ray">A ray.</param>
        /// <returns>The distance between the <paramref name="boundingBox"/> and the <paramref name="ray"/>.</returns>
        public static Number BoundingBoxToRay(BoundingBox boundingBox, Ray ray)
        {
            var center = (boundingBox.Minimum + boundingBox.Maximum) / 2;
            var u = Vector3.Dot(center - ray.Position, ray.Direction) / ray.Direction.MagnitudeSquared;

            if (u < 0)
            {
                u = 0;
            }

            var closestPoint = ray.Position + u * ray.Direction;

            if (u > 0 && u < 1)
            {
                var normal = Vector3.Normalize(center - closestPoint);
                return BoundingBoxToPlane(boundingBox, new Plane(normal, closestPoint));
            }
            else
            {
                return PointToBoundingBox(closestPoint, boundingBox);
            }
        }
Exemple #9
0
        /// <summary>
        /// Determines whether the specified plane intersects with the specified bounding box.
        /// </summary>
        /// <param name="plane">A plane.</param>
        /// <param name="boundingBox">A bounding box.</param>
        /// <returns>True if the <paramref name="plane"/> and the <paramref name="boundingBox"/> intersect, otherwise false.</returns>
        public static bool PlaneWithBoundingBox(Plane plane, BoundingBox boundingBox)
        {
            var min = new Vector3
            {
                X = plane.A > 0 ? boundingBox.Minimum.X : boundingBox.Maximum.X,
                Y = plane.B > 0 ? boundingBox.Minimum.Y : boundingBox.Maximum.Y,
                Z = plane.C > 0 ? boundingBox.Minimum.Z : boundingBox.Maximum.Z,
            };

            if (Distance.PointToPlane(min, plane) > 0)
            {
                return false;
            }

            var max = new Vector3
            {
                X = plane.A < 0 ? boundingBox.Minimum.X : boundingBox.Maximum.X,
                Y = plane.B < 0 ? boundingBox.Minimum.Y : boundingBox.Maximum.Y,
                Z = plane.C < 0 ? boundingBox.Minimum.Z : boundingBox.Maximum.Z,
            };

            if (Distance.PointToPlane(max, plane) < 0)
            {
                return false;
            }

            return true;
        }
Exemple #10
0
        /// <summary>
        /// Determines whether the specified bounding box intersects with the specified ray.
        /// </summary>
        /// <param name="boundingBox">A bounding box.</param>
        /// <param name="ray">A ray.</param>
        /// <returns>True if the <paramref name="boundingBox"/> and the <paramref name="ray"/> intersect, otherwise false.</returns>
        public static bool BoundingBoxWithRay(BoundingBox boundingBox, Ray ray)
        {
            var n = Number.MinValue;
            var f = Number.MaxValue;

            if (Float.Near(ray.Direction.X, 0))
            {
                if (ray.Position.X < boundingBox.Minimum.X || ray.Position.X > boundingBox.Maximum.X)
                {
                    return false;
                }
            }
            else
            {
                var inv = 1 / ray.Direction.X;
                var d1 = (boundingBox.Minimum.X - ray.Position.X) * inv;
                var d2 = (boundingBox.Maximum.X - ray.Position.X) * inv;

                n = Math.Max(n, Math.Min(d1, d2));
                f = Math.Min(f, Math.Max(d1, d2));

                if (n > f || f < 0)
                {
                    return false;
                }
            }

            if (Float.Near(ray.Direction.Y, 0))
            {
                if (ray.Position.Y < boundingBox.Minimum.Y || ray.Position.Y > boundingBox.Maximum.Y)
                {
                    return false;
                }
            }
            else
            {
                var inv = 1 / ray.Direction.Y;
                var d1 = (boundingBox.Minimum.Y - ray.Position.Y) * inv;
                var d2 = (boundingBox.Maximum.Y - ray.Position.Y) * inv;

                n = Math.Max(n, Math.Min(d1, d2));
                f = Math.Min(f, Math.Max(d1, d2));

                if (n > f || f < 0)
                {
                    return false;
                }
            }

            if (Float.Near(ray.Direction.Z, 0))
            {
                if (ray.Position.Z < boundingBox.Minimum.Z || ray.Position.Z > boundingBox.Maximum.Z)
                {
                    return false;
                }
            }
            else
            {
                var inv = 1 / ray.Direction.Z;
                var d1 = (boundingBox.Minimum.Z - ray.Position.Z) * inv;
                var d2 = (boundingBox.Maximum.Z - ray.Position.Z) * inv;

                n = Math.Max(n, Math.Min(d1, d2));
                f = Math.Min(f, Math.Max(d1, d2));

                if (n > f || f < 0)
                {
                    return false;
                }
            }

            return true;
        }
Exemple #11
0
 /// <summary>
 /// Determines whether any of the fields of the specified bounding box evaluates to positive infinity.
 /// </summary>
 /// <param name="value">A bounding box.</param>
 /// <returns>True if any of the fields of <paramref name="value"/> evaluates to positive infinity, otherwise false.</returns>
 public static bool IsPositiveInfinity(BoundingBox value)
 {
     return
         Vector3.IsPositiveInfinity(value.Minimum) ||
         Vector3.IsPositiveInfinity(value.Maximum);
 }
Exemple #12
0
 /// <summary>
 /// Determines whether any of the fields of the specified bounding box evaluates to a value that is not a number.
 /// </summary>
 /// <param name="value">A bounding box.</param>
 /// <returns>True if any of the fields of <paramref name="value"/> evaluates to a value that is not a number, otherwise false.</returns>
 public static bool IsNaN(BoundingBox value)
 {
     return
         Vector3.IsNaN(value.Minimum) ||
         Vector3.IsNaN(value.Maximum);
 }
Exemple #13
0
        /// <summary>
        /// Returns the distance between the specified bounding box and the specified line segment.
        /// </summary>
        /// <param name="boundingBox">A bounding box.</param>
        /// <param name="lineSegment">A line segment.</param>
        /// <returns>The distance between the <paramref name="boundingBox"/> and the <paramref name="lineSegment"/>.</returns>
        public static Number BoundingBoxToLineSegment(BoundingBox boundingBox, LineSegment lineSegment)
        {
            var center = (boundingBox.Minimum + boundingBox.Maximum) / 2;
            var t = lineSegment.End2 - lineSegment.End1;
            var u = Vector3.Dot(center - lineSegment.End1, t) / t.MagnitudeSquared;

            if (u < 0)
            {
                u = 0;
            }

            if (u > 1)
            {
                u = 1;
            }

            var closestPoint = lineSegment.End1 + u * t;

            if (u > 0 && u < 1)
            {
                var normal = Vector3.Normalize(center - closestPoint);
                return BoundingBoxToPlane(boundingBox, new Plane(normal, closestPoint));
            }
            else
            {
                return PointToBoundingBox(closestPoint, boundingBox);
            }
        }
Exemple #14
0
 /// <summary>
 /// Returns the distance between the specified bounding box and the specified bounding sphere.
 /// </summary>
 /// <param name="boundingBox">A bounding box.</param>
 /// <param name="boundingSphere">A bounding sphere.</param>
 /// <returns>The distance between the <paramref name="boundingBox"/> and the <paramref name="boundingSphere"/>.</returns>
 public static Number BoundingBoxToBoundingSphere(BoundingBox boundingBox, BoundingSphere boundingSphere)
 {
     var closestPoint = Vector3.Clamp(boundingSphere.Position, boundingBox.Minimum, boundingBox.Maximum);
     return Distance.PointToBoundingSphere(closestPoint, boundingSphere);
 }
Exemple #15
0
 /// <summary>
 /// Returns the distance between the specified point and the specified bounding box.
 /// </summary>
 /// <param name="point">A point.</param>
 /// <param name="boundingBox">A bounding box.</param>
 /// <returns>The distance between the <paramref name="point"/> and the <paramref name="boundingBox"/>.</returns>
 public static Number PointToBoundingBox(Vector3 point, BoundingBox boundingBox)
 {
     return Distance.PointToPoint(point, Vector3.Clamp(point, boundingBox.Minimum, boundingBox.Maximum));
 }
Exemple #16
0
        /// <summary>
        /// Determines whether the specified bounding box intersects with the specified bounding sphere.
        /// </summary>
        /// <param name="boundingBox">A bounding box.</param>
        /// <param name="boundingSphere">A bounding sphere.</param>
        /// <param name="intersection">Output variable for the intersection.</param>
        /// <returns>True if the <paramref name="boundingBox"/> and the <paramref name="boundingSphere"/> intersect, otherwise false.</returns>
        public static bool BoundingBoxWithBoundingSphere(BoundingBox boundingBox, BoundingSphere boundingSphere, out Vector3 intersection)
        {
            var closestPoint = Vector3.Clamp(boundingSphere.Position, boundingBox.Minimum, boundingBox.Maximum);

            if (Distance.PointToPointSquared(closestPoint, boundingSphere.Position) <= boundingSphere.Radius * boundingSphere.Radius)
            {
                intersection = closestPoint;
                return true;
            }
            else
            {
                intersection = default(Vector3);
                return false;
            }
        }
Exemple #17
0
 /// <summary>
 /// Determines whether the specified bounding box intersects with the specified point.
 /// </summary>
 /// <param name="boundingBox">A bounding box.</param>
 /// <param name="point">A point.</param>
 /// <returns>True if the <paramref name="boundingBox"/> and the <paramref name="point"/> intersect, otherwise false.</returns>
 public static bool BoundingBoxWithPoint(BoundingBox boundingBox, Vector3 point)
 {
     return
         boundingBox.Minimum.X <= point.X && point.X <= boundingBox.Maximum.X &&
         boundingBox.Minimum.Y <= point.Y && point.Y <= boundingBox.Maximum.Y &&
         boundingBox.Minimum.Z <= point.Z && point.Z <= boundingBox.Maximum.Z;
 }
Exemple #18
0
 /// <summary>
 /// Returns the smallest bounding box containing both of the specified bounding boxes.
 /// </summary>
 /// <param name="value1">A bounding box.</param>
 /// <param name="value2">A bounding box.</param>
 /// <returns>The smallest bounding box containing both of the <paramref name="value1"/> and the <paramref name="value2"/>.</returns>
 public static BoundingBox Merge(BoundingBox value1, BoundingBox value2)
 {
     return new BoundingBox
     {
         Minimum = Vector3.Min(value1.Minimum, value2.Minimum),
         Maximum = Vector3.Max(value1.Maximum, value2.Maximum),
     };
 }
Exemple #19
0
        /// <summary>
        /// Determines whether the specified bounding box intersects with the specified ray.
        /// </summary>
        /// <param name="boundingBox">A bounding box.</param>
        /// <param name="ray">A ray.</param>
        /// <param name="intersection">Output variable for the intersection.</param>
        /// <returns>True if the <paramref name="boundingBox"/> and the <paramref name="ray"/> intersect, otherwise false.</returns>
        public static bool BoundingBoxWithRay(BoundingBox boundingBox, Ray ray, out LineSegment intersection)
        {
            var n = Number.MinValue;
            var f = Number.MaxValue;

            if (Float.Near(ray.Direction.X, 0))
            {
                if (ray.Position.X < boundingBox.Minimum.X || ray.Position.X > boundingBox.Maximum.X)
                {
                    intersection = default(LineSegment);
                    return false;
                }
            }
            else
            {
                var inv = 1 / ray.Direction.X;
                var d1 = (boundingBox.Minimum.X - ray.Position.X) * inv;
                var d2 = (boundingBox.Maximum.X - ray.Position.X) * inv;

                n = Math.Max(n, Math.Min(d1, d2));
                f = Math.Min(f, Math.Max(d1, d2));

                if (n > f || f < 0)
                {
                    intersection = default(LineSegment);
                    return false;
                }
            }

            if (Float.Near(ray.Direction.Y, 0))
            {
                if (ray.Position.Y < boundingBox.Minimum.Y || ray.Position.Y > boundingBox.Maximum.Y)
                {
                    intersection = default(LineSegment);
                    return false;
                }
            }
            else
            {
                var inv = 1 / ray.Direction.Y;
                var d1 = (boundingBox.Minimum.Y - ray.Position.Y) * inv;
                var d2 = (boundingBox.Maximum.Y - ray.Position.Y) * inv;

                n = Math.Max(n, Math.Min(d1, d2));
                f = Math.Min(f, Math.Max(d1, d2));

                if (n > f || f < 0)
                {
                    intersection = default(LineSegment);
                    return false;
                }
            }

            if (Float.Near(ray.Direction.Z, 0))
            {
                if (ray.Position.Z < boundingBox.Minimum.Z || ray.Position.Z > boundingBox.Maximum.Z)
                {
                    intersection = default(LineSegment);
                    return false;
                }
            }
            else
            {
                var inv = 1 / ray.Direction.Z;
                var d1 = (boundingBox.Minimum.Z - ray.Position.Z) * inv;
                var d2 = (boundingBox.Maximum.Z - ray.Position.Z) * inv;

                n = Math.Max(n, Math.Min(d1, d2));
                f = Math.Min(f, Math.Max(d1, d2));

                if (n > f || f < 0)
                {
                    intersection = default(LineSegment);
                    return false;
                }
            }

            intersection = new LineSegment
            {
                End1 = ray.Position + ray.Direction * n,
                End2 = ray.Position + ray.Direction * f,
            };

            return true;
        }
Exemple #20
0
 /// <summary>
 /// Attempts to parse the bounding box from the specified string.
 /// </summary>
 /// <param name="value">The string to parse.</param>
 /// <param name="result">The output variable for the bounding box parsed from the <paramref name="value"/>.</param>
 /// <returns>True if the <paramref name="value"/> was parsed successfully, otherwise false.</returns>
 public static bool TryParse(string value, out BoundingBox result)
 {
     return TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, null, out result);
 }
Exemple #21
0
 /// <summary>
 /// Attempts to parse the bounding box from the specified string.
 /// </summary>
 /// <param name="value">The string to parse.</param>
 /// <param name="numberStyle">The number style for each component.</param>
 /// <param name="result">The output variable for the bounding box parsed from the <paramref name="value"/>.</param>
 /// <returns>True if the <paramref name="value"/> was parsed successfully, otherwise false.</returns>
 public static bool TryParse(string value, NumberStyles numberStyle, out BoundingBox result)
 {
     return TryParse(value, numberStyle, null, out result);
 }
Exemple #22
0
 /// <summary>
 /// Attempts to parse the bounding box from the specified string.
 /// </summary>
 /// <param name="value">The string to parse.</param>
 /// <param name="formatProvider">The format provider for each component.</param>
 /// <param name="result">The output variable for the bounding box parsed from the <paramref name="value"/>.</param>
 /// <returns>True if the <paramref name="value"/> was parsed successfully, otherwise false.</returns>
 public static bool TryParse(string value, IFormatProvider formatProvider, out BoundingBox result)
 {
     return TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, formatProvider, out result);
 }
Exemple #23
0
 /// <summary>
 /// Determines whether the specified bounding box intersects with the specified bounding sphere.
 /// </summary>
 /// <param name="boundingBox">A bounding box.</param>
 /// <param name="boundingSphere">A bounding sphere.</param>
 /// <returns>True if the <paramref name="boundingBox"/> and the <paramref name="boundingSphere"/> intersect, otherwise false.</returns>
 public static bool BoundingBoxWithBoundingSphere(BoundingBox boundingBox, BoundingSphere boundingSphere)
 {
     var closestPoint = Vector3.Clamp(boundingSphere.Position, boundingBox.Minimum, boundingBox.Maximum);
     return Distance.PointToPointSquared(boundingSphere.Position, closestPoint) <= boundingSphere.Radius * boundingSphere.Radius;
 }
Exemple #24
0
        /// <summary>
        /// Returns the distance between the specified bounding box and the specified plane.
        /// </summary>
        /// <param name="boundingBox">A bounding box.</param>
        /// <param name="plane">A plane.</param>
        /// <returns>The distance between the <paramref name="boundingBox"/> and the <paramref name="plane"/>.</returns>
        public static Number BoundingBoxToPlane(BoundingBox boundingBox, Plane plane)
        {
            var min = new Vector3
            {
                X = plane.A > 0 ? boundingBox.Minimum.X : boundingBox.Maximum.X,
                Y = plane.B > 0 ? boundingBox.Minimum.Y : boundingBox.Maximum.Y,
                Z = plane.C > 0 ? boundingBox.Minimum.Z : boundingBox.Maximum.Z,
            };

            var minDistance = Distance.PointToPlane(min, plane);

            if (minDistance >= 0)
            {
                return minDistance;
            }

            var max = new Vector3
            {
                X = plane.A < 0 ? boundingBox.Minimum.X : boundingBox.Maximum.X,
                Y = plane.B < 0 ? boundingBox.Minimum.Y : boundingBox.Maximum.Y,
                Z = plane.C < 0 ? boundingBox.Minimum.Z : boundingBox.Maximum.Z,
            };

            var maxDistance = Distance.PointToPlane(max, plane);

            if (maxDistance <= 0)
            {
                return maxDistance;
            }

            return 0;
        }