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;
}
}
}
}