public static Either <Null, Point2D, Segment2D> IntersectWithDisk(this Segment2D segment, Circle2D diskBoundary)
        {
            var lineIntersectionsWithBoundary = diskBoundary.IntersectWithLine(segment.AsLine()).ToList();

            if (lineIntersectionsWithBoundary.Count == 0)
            {
                return(Null.Instance);
            }

            if (lineIntersectionsWithBoundary.Count == 1)
            {
                var point = lineIntersectionsWithBoundary.Single();
                if (segment.Contains(point))
                {
                    return(point);
                }
                return(Null.Instance);
            }

            var segmentDirection = segment.GetDirection();

            var(baseSideIntersection, endSideIntersection) =
                (lineIntersectionsWithBoundary[0], lineIntersectionsWithBoundary[1]).ReverseIf(
                    (lineIntersectionsWithBoundary[0].DirectionTo(lineIntersectionsWithBoundary[1])
                     .Value
                     .DotProduct(segmentDirection)
                    ) < 0);

            var clipBase =
                (baseSideIntersection - segment.BasePoint).GetComponentInDirection(segmentDirection)
                > Unit.ZeroDistance;
            var clipEnd =
                (endSideIntersection - segment.EndPoint).GetComponentInDirection(segmentDirection) < Unit.ZeroDistance;

            var clippedBase = clipBase ? baseSideIntersection : segment.BasePoint;
            var clippedEnd  = clipEnd ? endSideIntersection : segment.EndPoint;

            if (clippedBase == clippedEnd)
            {
                return(clipBase ? segment.EndPoint : segment.BasePoint);
            }

            var signedDistance = (clippedEnd - clippedBase).GetComponentInDirection(segmentDirection);

            if (signedDistance > Unit.ZeroDistance)
            {
                return(new Segment2D(clippedBase, clippedEnd));
            }

            return(Null.Instance);
        }
Пример #2
0
        public void Property_IfSegmentsAreParallelAndIntersect_ItShouldBeAnEndPoint
        (
            Segment2D segment1,
            Segment2D segment2
        )
        {
            var intersection = segment1.IntersectWithSegment(segment2);

            if (
                segment1.GetDirection().IsParallelTo(segment2.GetDirection()) &&
                intersection.Is <Point2D>(out var point2D))
            {
                var point        = point2D.ToPoint3D();
                var isEndOfOneOf = point.IsBaseOrEndPointOf(segment1.To3D()) ||
                                   point.IsBaseOrEndPointOf(segment2.To3D());

                isEndOfOneOf.Should().BeTrue();
            }
        }