2024-04-18 01:29:47 +02:00
|
|
|
|
namespace GeometriCS
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
2024-04-19 00:42:56 +02:00
|
|
|
|
/// Intersection between a line and a line segment. Double precision.
|
2024-04-18 01:29:47 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
public class IntersectionLine2ToLineSegment2d
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Possible statuses the intersection can be.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public enum Statuses
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Intersection is valid.
|
|
|
|
|
/// </summary>
|
|
|
|
|
SUCCESS,
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The two lines are parallel.
|
|
|
|
|
/// </summary>
|
|
|
|
|
PARALLEL,
|
|
|
|
|
/// <summary>
|
2024-04-19 00:42:56 +02:00
|
|
|
|
/// The line segment is colinear with the line.
|
|
|
|
|
/// </summary>
|
|
|
|
|
COLINEAR,
|
|
|
|
|
/// <summary>
|
2024-04-18 01:29:47 +02:00
|
|
|
|
/// The intersection would happen if the intersectors were unbounded, but not inside the bounds.
|
|
|
|
|
/// </summary>
|
|
|
|
|
OUTOFBOUNDS,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The intersecting line.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Line2d Line { get; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The intersecting line segment.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public LineSegment2d LineSegment { get; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Status of the intersection.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Statuses Status { get; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The point of the intersection between the line and line segment.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Vector2d? Result { get; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Constructor for Line2d to LinearSegment2d intersection.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="line">The intersecting line.</param>
|
|
|
|
|
/// <param name="lineSegment">The intersecting lineSegment.</param>
|
|
|
|
|
public IntersectionLine2ToLineSegment2d(Line2d line, LineSegment2d lineSegment)
|
|
|
|
|
{
|
|
|
|
|
Line = line;
|
|
|
|
|
LineSegment = lineSegment;
|
|
|
|
|
|
2024-04-19 00:42:56 +02:00
|
|
|
|
// 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;
|
|
|
|
|
}
|
2024-04-18 01:29:47 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|