Example #1
0
        /// <summary>
        /// Computes an intersection of the segment and the circle
        /// </summary>
        public static bool SegmentCircle(Vector2 segmentA, Vector2 segmentB, Vector2 circleCenter, float circleRadius,
                                         out IntersectionSegmentCircle intersection)
        {
            Vector2 segmentAToCenter = circleCenter - segmentA;
            Vector2 fromAtoB         = segmentB - segmentA;
            float   segmentLength    = fromAtoB.magnitude;

            if (segmentLength < Geometry.Epsilon)
            {
                float distanceToPoint = segmentAToCenter.magnitude;
                if (distanceToPoint < circleRadius + Geometry.Epsilon)
                {
                    if (distanceToPoint > circleRadius - Geometry.Epsilon)
                    {
                        intersection = IntersectionSegmentCircle.Point(segmentA);
                        return(true);
                    }
                    intersection = IntersectionSegmentCircle.None();
                    return(true);
                }
                intersection = IntersectionSegmentCircle.None();
                return(false);
            }

            Vector2 segmentDirection = fromAtoB.normalized;
            float   centerProjection = Vector2.Dot(segmentDirection, segmentAToCenter);

            if (centerProjection + circleRadius < -Geometry.Epsilon ||
                centerProjection - circleRadius > segmentLength + Geometry.Epsilon)
            {
                intersection = IntersectionSegmentCircle.None();
                return(false);
            }

            float sqrDistanceToLine         = segmentAToCenter.sqrMagnitude - centerProjection * centerProjection;
            float sqrDistanceToIntersection = circleRadius * circleRadius - sqrDistanceToLine;

            if (sqrDistanceToIntersection < -Geometry.Epsilon)
            {
                intersection = IntersectionSegmentCircle.None();
                return(false);
            }

            if (sqrDistanceToIntersection < Geometry.Epsilon)
            {
                if (centerProjection < -Geometry.Epsilon ||
                    centerProjection > segmentLength + Geometry.Epsilon)
                {
                    intersection = IntersectionSegmentCircle.None();
                    return(false);
                }
                intersection = IntersectionSegmentCircle.Point(segmentA + segmentDirection * centerProjection);
                return(true);
            }

            // Line intersection
            float distanceToIntersection = Mathf.Sqrt(sqrDistanceToIntersection);
            float distanceA = centerProjection - distanceToIntersection;
            float distanceB = centerProjection + distanceToIntersection;

            bool pointAIsAfterSegmentA  = distanceA > -Geometry.Epsilon;
            bool pointBIsBeforeSegmentB = distanceB < segmentLength + Geometry.Epsilon;

            if (pointAIsAfterSegmentA && pointBIsBeforeSegmentB)
            {
                Vector2 pointA = segmentA + segmentDirection * distanceA;
                Vector2 pointB = segmentA + segmentDirection * distanceB;
                intersection = IntersectionSegmentCircle.TwoPoints(pointA, pointB);
                return(true);
            }
            if (!pointAIsAfterSegmentA && !pointBIsBeforeSegmentB)
            {
                // The segment is inside, but no intersection
                intersection = IntersectionSegmentCircle.None();
                return(true);
            }

            bool pointAIsBeforeSegmentB = distanceA < segmentLength + Geometry.Epsilon;

            if (pointAIsAfterSegmentA && pointAIsBeforeSegmentB)
            {
                // Point A intersection
                intersection = IntersectionSegmentCircle.Point(segmentA + segmentDirection * distanceA);
                return(true);
            }
            bool pointBIsAfterSegmentA = distanceB > -Geometry.Epsilon;

            if (pointBIsAfterSegmentA && pointBIsBeforeSegmentB)
            {
                // Point B intersection
                intersection = IntersectionSegmentCircle.Point(segmentA + segmentDirection * distanceB);
                return(true);
            }

            intersection = IntersectionSegmentCircle.None();
            return(false);
        }
Example #2
0
 /// <summary>
 /// Computes an intersection of the segment and the circle
 /// </summary>
 public static bool SegmentCircle(Segment2 segment, Circle2 circle, out IntersectionSegmentCircle intersection)
 {
     return(SegmentCircle(segment.a, segment.b, circle.center, circle.radius, out intersection));
 }