public static bool SegmentSegment()

in MREUnityRuntimeLib/ProceduralToolkit/Geometry/Intersect2D.cs [888:999]


		public static bool SegmentSegment(Vector2 segment1A, Vector2 segment1B, Vector2 segment2A, Vector2 segment2B,
			out IntersectionSegmentSegment2 intersection)
		{
			Vector2 from2ATo1A = segment1A - segment2A;
			Vector2 direction1 = segment1B - segment1A;
			Vector2 direction2 = segment2B - segment2A;

			float sqrSegment1Length = direction1.sqrMagnitude;
			float sqrSegment2Length = direction2.sqrMagnitude;
			bool segment1IsAPoint = sqrSegment1Length < Geometry.Epsilon;
			bool segment2IsAPoint = sqrSegment2Length < Geometry.Epsilon;
			if (segment1IsAPoint && segment2IsAPoint)
			{
				if (segment1A == segment2A)
				{
					intersection = IntersectionSegmentSegment2.Point(segment1A);
					return true;
				}
				intersection = IntersectionSegmentSegment2.None();
				return false;
			}
			if (segment1IsAPoint)
			{
				if (PointSegment(segment1A, segment2A, direction2, sqrSegment2Length))
				{
					intersection = IntersectionSegmentSegment2.Point(segment1A);
					return true;
				}
				intersection = IntersectionSegmentSegment2.None();
				return false;
			}
			if (segment2IsAPoint)
			{
				if (PointSegment(segment2A, segment1A, direction1, sqrSegment1Length))
				{
					intersection = IntersectionSegmentSegment2.Point(segment2A);
					return true;
				}
				intersection = IntersectionSegmentSegment2.None();
				return false;
			}

			float denominator = VectorE.PerpDot(direction1, direction2);
			float perpDot1 = VectorE.PerpDot(direction1, from2ATo1A);
			float perpDot2 = VectorE.PerpDot(direction2, from2ATo1A);

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

				bool codirected = Vector2.Dot(direction1, direction2) > 0;
				if (codirected)
				{
					// Codirected
					float segment2AProjection = -Vector2.Dot(direction1, from2ATo1A);
					if (segment2AProjection > -Geometry.Epsilon)
					{
						// 1A------1B
						//     2A------2B
						return SegmentSegmentCollinear(segment1A, segment1B, sqrSegment1Length, segment2A, segment2B, out intersection);
					}
					else
					{
						//     1A------1B
						// 2A------2B
						return SegmentSegmentCollinear(segment2A, segment2B, sqrSegment2Length, segment1A, segment1B, out intersection);
					}
				}
				else
				{
					// Contradirected
					float segment2BProjection = Vector2.Dot(direction1, segment2B - segment1A);
					if (segment2BProjection > -Geometry.Epsilon)
					{
						// 1A------1B
						//     2B------2A
						return SegmentSegmentCollinear(segment1A, segment1B, sqrSegment1Length, segment2B, segment2A, out intersection);
					}
					else
					{
						//     1A------1B
						// 2B------2A
						return SegmentSegmentCollinear(segment2B, segment2A, sqrSegment2Length, segment1A, segment1B, out intersection);
					}
				}
			}

			// Not parallel
			float distance1 = perpDot2/denominator;
			if (distance1 < -Geometry.Epsilon || distance1 > 1 + Geometry.Epsilon)
			{
				intersection = IntersectionSegmentSegment2.None();
				return false;
			}

			float distance2 = perpDot1/denominator;
			if (distance2 < -Geometry.Epsilon || distance2 > 1 + Geometry.Epsilon)
			{
				intersection = IntersectionSegmentSegment2.None();
				return false;
			}

			intersection = IntersectionSegmentSegment2.Point(segment1A + direction1*distance1);
			return true;
		}