namespace GeometriCS { /// /// Intersection between a line and a line segment. Double precision. /// public class IntersectionLine2ToLineSegment2d { /// /// Possible statuses the intersection can be. /// public enum Statuses { /// /// Intersection is valid. /// SUCCESS, /// /// The two lines are parallel. /// PARALLEL, /// /// The line segment is colinear with the line. /// COLINEAR, /// /// The intersection would happen if the intersectors were unbounded, but not inside the bounds. /// OUTOFBOUNDS, } /// /// The intersecting line. /// public Line2d Line { get; } /// /// The intersecting line segment. /// public LineSegment2d LineSegment { get; } /// /// Status of the intersection. /// public Statuses Status { get; } /// /// The point of the intersection between the line and line segment. /// public Vector2d? Result { get; } /// /// Constructor for Line2d to LinearSegment2d intersection. /// /// The intersecting line. /// The intersecting lineSegment. public IntersectionLine2ToLineSegment2d(Line2d line, LineSegment2d lineSegment) { Line = line; LineSegment = lineSegment; // Construct line coefficients for the linesegment (double segment_A, double segment_B, double segment_C) = Utils.Line2CoefficientsFromTwoPoints(lineSegment.StartPoint, lineSegment.EndPoint); // Check if lines are parallel // TODO: Check what happens if coeff_B == 0 // TODO: Find a non-retarded way to put this into a function so // that it can be reused by all the 2d linear intersections. if (Utils.DoubleEquals(line.Coeff_A / line.Coeff_B, segment_A / segment_B)) { // Null result Result = null; // Check if lines are coincidental if (Utils.DoubleEquals(line.Coeff_A / segment_A, line.Coeff_B / segment_B) && Utils.DoubleEquals(line.Coeff_A / segment_A, line.Coeff_C / segment_C)) { Status = Statuses.COLINEAR; } else { Status = Statuses.PARALLEL; } return; } // Perform the intersection calculation double divisor = line.Coeff_A * segment_B - segment_A * line.Coeff_B; double x0 = (line.Coeff_B * segment_C - segment_B * line.Coeff_C) / divisor; double y0 = (line.Coeff_C * segment_A - segment_C * line.Coeff_A) / divisor; Result = new Vector2d(x0, y0); // Check if result is inside of the segment. if (lineSegment.Extents.Contains((Vector2d)Result)) { Status = Statuses.SUCCESS; } else { Status = Statuses.OUTOFBOUNDS; } } } }