/// <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);
public static Distance DistanceTo(this Point2D point, BoundaryLine2D line) => line.HalfPlane.GetOffsetFromBoundaryTowardInside(point).AbsoluteValue();