using System;
using Ringtoets.Piping.Data;
using Ringtoets.Piping.IO.Properties;
namespace Ringtoets.Piping.IO.Calculation
{
///
/// This class contains general mathematical routines for 2D lines.
///
public static class Math2D
{
///
/// Constant which is used to precision errors in comparisons.
///
private const double epsilonForComparisons = 1e-8;
///
/// Determines the intersection point of a line which passes through the and
/// the ; and a line which passes through the
/// and the .
///
/// A which the first line passes through.
/// Another which the first line passes through.
/// A which the second line passes through.
/// Another which the second line passes through.
/// An with coordinates at the point where the lines intersect. Or null when no
/// intersection point exists (lines are parallel).
///
/// Taken from: https://www.topcoder.com/community/data-science/data-science-tutorials/geometry-concepts-line-intersection-and-its-applications/
/// Based on https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
///
/// Thrown when equals or
/// equals , which makes it impossible to determine
/// a line through the points.
public static Point2D LineIntersectionWithLine(Point2D line1Point1, Point2D line1Point2, Point2D line2Point1, Point2D line2Point2)
{
if (line1Point1.Equals(line1Point2) || line2Point1.Equals(line2Point2))
{
throw new ArgumentException(Resources.Math2D_LineIntersectionWithLine_Line_points_are_equal);
}
var aLine = line1Point2.Y - line1Point1.Y;
var bLine = line1Point1.X - line1Point2.X;
var cLine = aLine*line1Point1.X + bLine*line1Point1.Y;
var aOtherLine = line2Point2.Y - line2Point1.Y;
var bOtherLine = line2Point1.X - line2Point2.X;
var cOtherLine = aOtherLine*line2Point1.X + bOtherLine*line2Point1.Y;
var determinant = aLine*bOtherLine - aOtherLine*bLine;
if (Math.Abs(determinant) < epsilonForComparisons)
{
return null;
}
return new Point2D
{
X = (bOtherLine*cLine - bLine*cOtherLine)/determinant,
Y = (aLine*cOtherLine - aOtherLine*cLine)/determinant
};
}
}
}