/// <returns>
        /// the intersection of the two lines if it is a point, or <c>null</c> otherwise
        /// </returns>
        public static Point2D?PointIntersectionWithLine(this BoundaryLine2D line1, Line2D line2)
        {
            var dotProduct = line1.HalfPlane.DirectionTowardInterior.DotProduct(line2.Direction);

            if (Math.Abs(dotProduct) <= Unit.ZeroDotProductTolerance)
            {
                // The lines are approximately parallel.
                return(null);
            }
            return(line1.PointIntersectionWithLineUnstable(line2.GetPortSide().Boundary));
        }
        /// <returns>
        /// the point intersection of the two lines, even if the lines are nearly parallel
        /// </returns>
        public static Point2D PointIntersectionWithLineUnstable(this BoundaryLine2D line1, BoundaryLine2D line2)
        {
            var dotProduct =
                line1.HalfPlane.DirectionTowardInterior.DotProduct(line2.HalfPlane.DirectionHavingInteriorOnPortSide);

            // If both lines pass through the origin, then the intersection is the origin. Otherwise, if a line is
            // displaced from the origin, we need to adjust the intersection point. The first term below is the
            // adjustment we need to apply to account for the offset from the origin of line1, and the second term is
            // the adjustment we need to account for the offset from the origin of line2.
            return
                (new Point2D(
                     line2.HalfPlane.DirectionHavingInteriorOnPortSide.ToVector(
                         line1.HalfPlane.OffsetFromOrigin / dotProduct
                         ) - line1.HalfPlane
                     .DirectionHavingInteriorOnPortSide
                     .ToVector(line2.HalfPlane.OffsetFromOrigin / dotProduct)));
        }
        public static IEnumerable <Point2D> IntersectWithLine(this Circle2D circle, BoundaryLine2D line)
        {
            var offsetToCenter = line.HalfPlane.GetOffsetFromBoundaryTowardInside(circle.Center);

            if (!(offsetToCenter.AbsoluteValue() <= circle.Radius))
            {
                return(Enumerable.Empty <Point2D>());
            }

            var intersectionOfLineWithPerpendicularRadius =
                circle.Center + line.HalfPlane.DirectionTowardInterior.ToVector(-offsetToCenter);

            var distanceFromPerpendicularRadiusToIntersectionsSquared =
                circle.Radius.Square() - offsetToCenter.Square();

            // If it's negative, the line doesn't quite intersect the circle.

            if (distanceFromPerpendicularRadiusToIntersectionsSquared > Unit.ZeroArea)
            {
                var distanceFromPerpendicularRadiusToIntersections =
                    distanceFromPerpendicularRadiusToIntersectionsSquared.SquareRoot();

                var intersectionPoints =
                    line
                    .ParallelDirections
                    .Select(direction =>
                            intersectionOfLineWithPerpendicularRadius
                            + direction.ToVector(distanceFromPerpendicularRadiusToIntersections))
                    .ToList();

                if (intersectionPoints.DistinctEquatable().Count() > 1)
                {
                    return(intersectionPoints);
                }
            }

            return(intersectionOfLineWithPerpendicularRadius.Singleton());
        }
        public static Either <Null, Point2D, Segment2D> IntersectWithLine(this Segment2D segment, BoundaryLine2D line)
        {
            var baseOffset = line.HalfPlane.GetOffsetFromBoundaryTowardInside(segment.BasePoint);
            var endOffset  = line.HalfPlane.GetOffsetFromBoundaryTowardInside(segment.EndPoint);

            var lineContainsBase = baseOffset == Unit.ZeroDistance;
            var lineContainsEnd  = endOffset == Unit.ZeroDistance;

            if (lineContainsBase && lineContainsEnd)
            {
                return(segment);
            }

            if (baseOffset.Sign() != endOffset.Sign())
            {
                return(segment.AsLine().PointIntersectionWithLineUnstable(line));
            }

            if (lineContainsBase)
            {
                return(segment.BasePoint);
            }

            if (lineContainsEnd)
            {
                return(segment.EndPoint);
            }

            return(Null.Instance);
        }
 /// <returns>
 /// the point intersection of the two lines, even if the lines are nearly parallel
 /// </returns>
 public static Point2D PointIntersectionWithLineUnstable(this Line2D line1, BoundaryLine2D line2) =>
 line1.AsBoundaryLine().PointIntersectionWithLineUnstable(line2);
예제 #6
0
 public static Distance DistanceTo(this Point2D point, BoundaryLine2D line) =>
 line.HalfPlane.GetOffsetFromBoundaryTowardInside(point).AbsoluteValue();