public static void RayRay()

in MREUnityRuntimeLib/ProceduralToolkit/Geometry/Closest2D.cs [429:568]


		public static void RayRay(Vector2 originA, Vector2 directionA, Vector2 originB, Vector2 directionB,
			out Vector2 pointA, out Vector2 pointB)
		{
			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)
					{
						if (originBProjection > -Geometry.Epsilon)
						{
							// Projection of originA is on rayB
							pointA = originA;
							pointB = originB + directionA*originBProjection;
							return;
						}
						else
						{
							pointA = originA - directionA*originBProjection;
							pointB = originB;
							return;
						}
					}
					else
					{
						if (originBProjection > 0)
						{
							pointA = originA;
							pointB = originB;
							return;
						}
						else
						{
							// Projection of originA is on rayB
							pointA = originA;
							pointB = originB + directionA*originBProjection;
							return;
						}
					}
				}
				// Collinear

				if (codirected)
				{
					// Ray intersection
					if (originBProjection > -Geometry.Epsilon)
					{
						// Projection of originA is on rayB
						pointA = pointB = originA;
						return;
					}
					else
					{
						pointA = pointB = originB;
						return;
					}
				}
				else
				{
					if (originBProjection > 0)
					{
						// No intersection
						pointA = originA;
						pointB = originB;
						return;
					}
					else
					{
						// Segment intersection
						pointA = pointB = originA;
						return;
					}
				}
			}

			// 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)
					{
						pointA = originA;
						pointB = originB + directionB*originAProjection;
						return;
					}
					float originBProjection = -Vector2.Dot(directionA, originBToA);
					if (originBProjection > -Geometry.Epsilon)
					{
						pointA = originA + directionA*originBProjection;
						pointB = originB;
						return;
					}
					pointA = originA;
					pointB = originB;
					return;
				}
				else
				{
					if (distanceA > -Geometry.Epsilon)
					{
						float originBProjection = -Vector2.Dot(directionA, originBToA);
						if (originBProjection > -Geometry.Epsilon)
						{
							pointA = originA + directionA*originBProjection;
							pointB = originB;
							return;
						}
					}
					else if (distanceB > -Geometry.Epsilon)
					{
						float originAProjection = Vector2.Dot(directionB, originBToA);
						if (originAProjection > -Geometry.Epsilon)
						{
							pointA = originA;
							pointB = originB + directionB*originAProjection;
							return;
						}
					}
					pointA = originA;
					pointB = originB;
					return;
				}
			}
			// Point intersection
			pointA = pointB = originA + directionA*distanceA;
		}