public static float RayRay()

in MREUnityRuntimeLib/ProceduralToolkit/Geometry/Distance2D.cs [291:387]


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

			bool codirected = Vector2.Dot(directionA, directionB) > 0;
			if (Mathf.Abs(denominator) < Geometry.Epsilon)
			{
				// Parallel
				float originBProjection = -Vector2.Dot(directionA, originBToA);
				if (Mathf.Abs(perpDotA) > Geometry.Epsilon || Mathf.Abs(perpDotB) > Geometry.Epsilon)
				{
					// Not collinear
					if (!codirected && originBProjection < Geometry.Epsilon)
					{
						return Vector2.Distance(originA, originB);
					}
					float distanceSqr = originBToA.sqrMagnitude - originBProjection*originBProjection;
					// distanceSqr can be negative
					return distanceSqr <= 0 ? 0 : Mathf.Sqrt(distanceSqr);
				}
				// Collinear

				if (codirected)
				{
					// Ray intersection
					return 0;
				}
				else
				{
					if (originBProjection < Geometry.Epsilon)
					{
						// No intersection
						return Vector2.Distance(originA, originB);
					}
					else
					{
						// Segment intersection
						return 0;
					}
				}
			}

			// Not parallel
			float distanceA = perpDotB/denominator;
			float distanceB = perpDotA/denominator;
			if (distanceA < -Geometry.Epsilon || distanceB < -Geometry.Epsilon)
			{
				// No intersection
				if (codirected)
				{
					float originAProjection = Vector2.Dot(directionB, originBToA);
					if (originAProjection > -Geometry.Epsilon)
					{
						Vector2 rayPointA = originA;
						Vector2 rayPointB = originB + directionB*originAProjection;
						return Vector2.Distance(rayPointA, rayPointB);
					}
					float originBProjection = -Vector2.Dot(directionA, originBToA);
					if (originBProjection > -Geometry.Epsilon)
					{
						Vector2 rayPointA = originA + directionA*originBProjection;
						Vector2 rayPointB = originB;
						return Vector2.Distance(rayPointA, rayPointB);
					}
					return Vector2.Distance(originA, originB);
				}
				else
				{
					if (distanceA > -Geometry.Epsilon)
					{
						float originBProjection = -Vector2.Dot(directionA, originBToA);
						if (originBProjection > -Geometry.Epsilon)
						{
							Vector2 rayPointA = originA + directionA*originBProjection;
							Vector2 rayPointB = originB;
							return Vector2.Distance(rayPointA, rayPointB);
						}
					}
					else if (distanceB > -Geometry.Epsilon)
					{
						float originAProjection = Vector2.Dot(directionB, originBToA);
						if (originAProjection > -Geometry.Epsilon)
						{
							Vector2 rayPointA = originA;
							Vector2 rayPointB = originB + directionB*originAProjection;
							return Vector2.Distance(rayPointA, rayPointB);
						}
					}
					return Vector2.Distance(originA, originB);
				}
			}
			// Point intersection
			return 0;
		}