/// <summary>
        /// Calculates the squared distance between a given point and a given ray.
        /// </summary>
        /// <param name="point">A <see cref="Vector2F"/> instance.</param>
        /// <param name="ray">A <see cref="Ray"/> instance.</param>
        /// <returns>The squared distance between the point and the ray.</returns>
        public static float SquaredDistance(Vector2F point, Ray ray)
        {
            Vector2F diff = point - ray.Origin;
            float    t    = Vector2F.DotProduct(diff, ray.Direction);

            if (t <= 0.0f)
            {
                t = 0.0f;
            }
            else
            {
                t    /= ray.Direction.GetLengthSquared();
                diff -= t * ray.Direction;
            }

            return(diff.GetLengthSquared());
        }
Exemple #2
0
        /// <summary>
        /// Find the intersection of a ray and a sphere.
        /// Only works with unit rays (normalized direction)!!!
        /// </summary>
        /// <remarks>
        /// This is the optimized Ray-Sphere intersection algorithms described in "Real-Time Rendering".
        /// </remarks>
        /// <param name="ray">The ray to test.</param>
        /// <param name="t">
        /// If intersection accurs, the function outputs the distance from the ray's origin
        /// to the closest intersection point to this parameter.
        /// </param>
        /// <returns>Returns True if the ray intersects the sphere. otherwise, <see langword="false"/>.</returns>
        public bool FindIntersections(Ray ray, ref float t)
        {
            // Only gives correct result for unit rays.
            //Debug.Assert(MathUtils.ApproxEquals(1.0f, ray.Direction.GetLength()), "Ray direction should be normalized!");

            // Calculates a vector from the ray origin to the sphere center.
            Vector2F diff = this.center - ray.Origin;
            // Compute the projection of diff onto the ray direction
            float d = Vector2F.DotProduct(diff, ray.Direction);

            float diffSquared   = diff.GetLengthSquared();
            float radiusSquared = this.radius * this.radius;

            // First rejection test :
            // if d<0 and the ray origin is outside the sphere than the sphere is behind the ray
            if ((d < 0.0f) && (diffSquared > radiusSquared))
            {
                return(false);
            }

            // Compute the distance from the sphere center to the projection
            float mSquared = diffSquared - d * d;

            // Second rejection test:
            // if mSquared > radiusSquared than the ray misses the sphere
            if (mSquared > radiusSquared)
            {
                return(false);
            }

            float q = (float)System.Math.Sqrt(radiusSquared - mSquared);

            // We are interested only in the first intersection point:
            if (diffSquared > radiusSquared)
            {
                // If the origin is outside the sphere t = d - q is the first intersection point
                t = d - q;
            }
            else
            {
                // If the origin is inside the sphere t = d + q is the first intersection point
                t = d + q;
            }
            return(true);
        }
        /// <summary>
        /// Calculates the squared distance between a point and a solid oriented box.
        /// </summary>
        /// <param name="point">A <see cref="Vector2F"/> instance.</param>
        /// <param name="obb">An <see cref="OrientedBox"/> instance.</param>
        /// <param name="closestPoint">The closest point in box coordinates.</param>
        /// <returns>The squared distance between a point and a solid oriented box.</returns>
        /// <remarks>
        /// Treating the oriented box as solid means that any point inside the box has
        /// distance zero from the box.
        /// </remarks>
        public static float SquaredDistancePointSolidOrientedBox(Vector2F point, OrientedBox obb, out Vector2F closestPoint)
        {
            Vector2F diff    = point - obb.Center;
            Vector2F closest = new Vector2F(
                Vector2F.DotProduct(diff, obb.Axis1),
                Vector2F.DotProduct(diff, obb.Axis2));

            float sqrDist = 0.0f;
            float delta   = 0.0f;

            if (closest.X < -obb.Extent1)
            {
                delta     = closest.X + obb.Extent1;
                sqrDist  += delta * delta;
                closest.X = -obb.Extent1;
            }
            else if (closest.X > obb.Extent1)
            {
                delta     = closest.X - obb.Extent1;
                sqrDist  += delta * delta;
                closest.X = obb.Extent1;
            }

            if (closest.Y < -obb.Extent2)
            {
                delta     = closest.Y + obb.Extent2;
                sqrDist  += delta * delta;
                closest.Y = -obb.Extent2;
            }
            else if (closest.Y > obb.Extent2)
            {
                delta     = closest.Y - obb.Extent2;
                sqrDist  += delta * delta;
                closest.Y = obb.Extent2;
            }

            closestPoint = closest;

            return(sqrDist);
        }