/// <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); }
/// <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); }