/// <summary>
 /// Computes an intersection of the rays
 /// </summary>
 public static bool IntersectRayRay(Ray2D rayA, Ray2D rayB, out IntersectionRayRay2 intersection)
 {
     return(IntersectRayRay(rayA.origin, rayA.direction, rayB.origin, rayB.direction, out intersection));
 }
        /// <summary>
        /// Computes an intersection of the rays
        /// </summary>
        public static bool IntersectRayRay(Vector2 originA, Vector2 directionA, Vector2 originB, Vector2 directionB,
                                           out IntersectionRayRay2 intersection)
        {
            intersection = new IntersectionRayRay2();

            Vector2 originBToA  = originA - originB;
            float   denominator = VectorE.PerpDot(directionA, directionB);
            float   perpDotA    = VectorE.PerpDot(directionA, originBToA);
            float   perpDotB    = VectorE.PerpDot(directionB, originBToA);

            if (Mathf.Abs(denominator) < Epsilon)
            {
                // Parallel
                if (Mathf.Abs(perpDotA) > Epsilon || Mathf.Abs(perpDotB) > Epsilon)
                {
                    // Not collinear
                    intersection.type = IntersectionType.None;
                    return(false);
                }
                // Collinear

                bool  codirected = Vector2.Dot(directionA, directionB) > 0;
                float dotA       = Vector2.Dot(directionA, originBToA);
                if (codirected)
                {
                    intersection.type   = IntersectionType.Ray;
                    intersection.pointA = dotA > 0 ? originA : originB;
                    intersection.pointB = directionA;
                    return(true);
                }
                else
                {
                    if (dotA > 0)
                    {
                        intersection.type = IntersectionType.None;
                        return(false);
                    }
                    else
                    {
                        intersection.type   = IntersectionType.Segment;
                        intersection.pointA = originA;
                        intersection.pointB = originB;
                        return(true);
                    }
                }
            }

            // The rays are skew and may intersect in a point
            float distanceA = perpDotB / denominator;

            if (distanceA < -Epsilon)
            {
                intersection.type = IntersectionType.None;
                return(false);
            }

            float distanceB = perpDotA / denominator;

            if (distanceB < -Epsilon)
            {
                intersection.type = IntersectionType.None;
                return(false);
            }

            intersection.type   = IntersectionType.Point;
            intersection.pointA = originA + directionA * distanceA;
            return(true);
        }
Esempio n. 3
0
        /// <summary>
        /// Computes an intersection of the rays
        /// </summary>
        public static bool RayRay(Vector2 originA, Vector2 directionA, Vector2 originB, Vector2 directionB,
                                  out IntersectionRayRay2 intersection)
        {
            Vector2 originBToA  = originA - originB;
            float   denominator = VectorE.PerpDot(directionA, directionB);
            float   perpDotA    = VectorE.PerpDot(directionA, originBToA);
            float   perpDotB    = VectorE.PerpDot(directionB, originBToA);

            if (Mathf.Abs(denominator) < Geometry.Epsilon)
            {
                // Parallel
                if (Mathf.Abs(perpDotA) > Geometry.Epsilon || Mathf.Abs(perpDotB) > Geometry.Epsilon)
                {
                    // Not collinear
                    intersection = IntersectionRayRay2.None();
                    return(false);
                }
                // Collinear

                bool  codirected        = Vector2.Dot(directionA, directionB) > 0;
                float originBProjection = -Vector2.Dot(directionA, originBToA);
                if (codirected)
                {
                    intersection = IntersectionRayRay2.Ray(originBProjection > 0 ? originB : originA, directionA);
                    return(true);
                }
                else
                {
                    if (originBProjection < -Geometry.Epsilon)
                    {
                        intersection = IntersectionRayRay2.None();
                        return(false);
                    }
                    if (originBProjection < Geometry.Epsilon)
                    {
                        intersection = IntersectionRayRay2.Point(originA);
                        return(true);
                    }
                    intersection = IntersectionRayRay2.Segment(originA, originB);
                    return(true);
                }
            }

            // Not parallel
            float distanceA = perpDotB / denominator;

            if (distanceA < -Geometry.Epsilon)
            {
                intersection = IntersectionRayRay2.None();
                return(false);
            }

            float distanceB = perpDotA / denominator;

            if (distanceB < -Geometry.Epsilon)
            {
                intersection = IntersectionRayRay2.None();
                return(false);
            }

            intersection = IntersectionRayRay2.Point(originA + directionA * distanceA);
            return(true);
        }