Пример #1
0
        /// <summary>
        /// Computes an intersection of the line and the segment
        /// </summary>
        public static bool LineSegment(Vector2 lineOrigin, Vector2 lineDirection, Vector2 segmentA, Vector2 segmentB,
                                       out IntersectionLineSegment2 intersection)
        {
            Vector2 segmentAToOrigin = lineOrigin - segmentA;
            Vector2 segmentDirection = segmentB - segmentA;
            float   denominator      = VectorE.PerpDot(lineDirection, segmentDirection);
            float   perpDotA         = VectorE.PerpDot(lineDirection, segmentAToOrigin);

            if (Mathf.Abs(denominator) < Geometry.Epsilon)
            {
                // Parallel
                // Normalized direction gives more stable results
                float perpDotB = VectorE.PerpDot(segmentDirection.normalized, segmentAToOrigin);
                if (Mathf.Abs(perpDotA) > Geometry.Epsilon || Mathf.Abs(perpDotB) > Geometry.Epsilon)
                {
                    // Not collinear
                    intersection = IntersectionLineSegment2.None();
                    return(false);
                }
                // Collinear
                bool segmentIsAPoint = segmentDirection.sqrMagnitude < Geometry.Epsilon;
                if (segmentIsAPoint)
                {
                    intersection = IntersectionLineSegment2.Point(segmentA);
                    return(true);
                }

                bool codirected = Vector2.Dot(lineDirection, segmentDirection) > 0;
                if (codirected)
                {
                    intersection = IntersectionLineSegment2.Segment(segmentA, segmentB);
                }
                else
                {
                    intersection = IntersectionLineSegment2.Segment(segmentB, segmentA);
                }
                return(true);
            }

            // Not parallel
            float segmentDistance = perpDotA / denominator;

            if (segmentDistance > -Geometry.Epsilon && segmentDistance < 1 + Geometry.Epsilon)
            {
                intersection = IntersectionLineSegment2.Point(segmentA + segmentDirection * segmentDistance);
                return(true);
            }
            intersection = IntersectionLineSegment2.None();
            return(false);
        }
        /// <summary>
        /// Computes an intersection of the line and the segment
        /// </summary>
        public static bool LineSegment(Vector2 lineOrigin, Vector2 lineDirection, Vector2 segmentA, Vector2 segmentB,
                                       out IntersectionLineSegment2 intersection)
        {
            float   lineDistance;
            float   segmentDistance;
            Vector2 segmentDirection = segmentB - segmentA;
            var     intersectionType = LineLine(lineOrigin, lineDirection, segmentA, segmentDirection, out lineDistance, out segmentDistance);

            if (intersectionType == IntersectionType.Line)
            {
                bool segmentIsAPoint = segmentDirection.sqrMagnitude < Geometry.Epsilon;
                if (segmentIsAPoint)
                {
                    intersection = IntersectionLineSegment2.Point(segmentA);
                    return(true);
                }

                bool codirected = Vector2.Dot(lineDirection, segmentB - segmentA) > 0;
                if (codirected)
                {
                    intersection = IntersectionLineSegment2.Segment(segmentA, segmentB);
                }
                else
                {
                    intersection = IntersectionLineSegment2.Segment(segmentB, segmentA);
                }
                return(true);
            }
            if (intersectionType == IntersectionType.Point &&
                segmentDistance > -Geometry.Epsilon && segmentDistance < 1 + Geometry.Epsilon)
            {
                intersection = IntersectionLineSegment2.Point(lineOrigin + lineDirection * lineDistance);
                return(true);
            }

            intersection = IntersectionLineSegment2.None();
            return(false);
        }