Index: Core/Common/src/Core.Common.Base/Core.Common.Base.csproj
===================================================================
diff -u -r93b256575fba3e4068baadeeb62140533336371a -r1b4f4720632f9a691837fa97e777a4637b6739c8
--- Core/Common/src/Core.Common.Base/Core.Common.Base.csproj (.../Core.Common.Base.csproj) (revision 93b256575fba3e4068baadeeb62140533336371a)
+++ Core/Common/src/Core.Common.Base/Core.Common.Base.csproj (.../Core.Common.Base.csproj) (revision 1b4f4720632f9a691837fa97e777a4637b6739c8)
@@ -88,11 +88,13 @@
Properties\GlobalAssembly.cs
+
+
Index: Core/Common/src/Core.Common.Base/Geometry/Intersection2DType.cs
===================================================================
diff -u
--- Core/Common/src/Core.Common.Base/Geometry/Intersection2DType.cs (revision 0)
+++ Core/Common/src/Core.Common.Base/Geometry/Intersection2DType.cs (revision 1b4f4720632f9a691837fa97e777a4637b6739c8)
@@ -0,0 +1,21 @@
+namespace Core.Common.Base.Geometry
+{
+ ///
+ /// Describes the type of intersection that has been calculated in 2D Euclidean space.
+ ///
+ public enum Intersection2DType
+ {
+ ///
+ /// No intersections have been found.
+ ///
+ NoIntersections,
+ ///
+ /// Intersections have been found.
+ ///
+ Intersects,
+ ///
+ /// There is some overlap between two elements.
+ ///
+ Overlapping
+ }
+}
\ No newline at end of file
Index: Core/Common/src/Core.Common.Base/Geometry/Math2D.cs
===================================================================
diff -u -rd36a95d2e88d98b7b92ff5d091abf711d1dd31d9 -r1b4f4720632f9a691837fa97e777a4637b6739c8
--- Core/Common/src/Core.Common.Base/Geometry/Math2D.cs (.../Math2D.cs) (revision d36a95d2e88d98b7b92ff5d091abf711d1dd31d9)
+++ Core/Common/src/Core.Common.Base/Geometry/Math2D.cs (.../Math2D.cs) (revision 1b4f4720632f9a691837fa97e777a4637b6739c8)
@@ -24,6 +24,8 @@
using System.Collections.ObjectModel;
using System.Linq;
using Core.Common.Base.Properties;
+
+using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
namespace Core.Common.Base.Geometry
@@ -225,6 +227,178 @@
return length;
}
+ ///
+ /// Calculates the intersection between two 2D segments.
+ ///
+ /// The first 2D segment.
+ /// The second 2D segment.
+ /// The intersection calculation result.
+ /// Implementation from http://geomalgorithms.com/a05-_intersect-1.html
+ /// based on method intersect2D_2Segments.
+ public static Segment2DIntersectSegment2DResult GetIntersectionBetweenSegments(Segment2D segment1, Segment2D segment2)
+ {
+ Vector u = segment1.SecondPoint - segment1.FirstPoint;
+ Vector v = segment2.SecondPoint - segment2.FirstPoint;
+ Vector w = segment1.FirstPoint - segment2.FirstPoint;
+ double d = PerpDotProduct(u, v);
+
+ if (Math.Abs(d) < epsilonForComparisons)
+ {
+ // Segments can be considered parallel...
+ if (AreCollinear(u, v, w))
+ {
+ // ... and collinear ...
+ if (IsSegmentAsPointIntersectionDegenerateScenario(segment1, segment2))
+ {
+ // ... but either or both segments are point degenerates:
+ return HandleSegmentAsPointIntersectionDegenerates(segment1, segment2);
+ }
+
+ // ... so there is a possibility of overlapping or connected lines:
+ return HandleCollinearSegmentIntersection(segment1, segment2, v, w);
+ }
+
+ // ... but not collinear, so no intersection possible:
+ return Segment2DIntersectSegment2DResult.CreateNoIntersectResult();
+ }
+ else
+ {
+ // Segments are at an angle and may intersect:
+ double sI = PerpDotProduct(v, w) / d;
+ if (sI < 0.0 || sI > 1.0)
+ {
+ return Segment2DIntersectSegment2DResult.CreateNoIntersectResult();
+ }
+
+ double tI = PerpDotProduct(u, w) / d;
+ if (tI < 0.0 || tI > 1.0)
+ {
+ return Segment2DIntersectSegment2DResult.CreateNoIntersectResult();
+ }
+
+ Point2D intersectionPoint = segment1.FirstPoint + u.Multiply(sI);
+ return Segment2DIntersectSegment2DResult.CreateIntersectionResult(intersectionPoint);
+ }
+ }
+
+ ///
+ /// Determines if two vectors are collinear.
+ ///
+ /// The first 2D vector.
+ /// The second 2D vector.
+ /// The vector from the tail of
+ /// to the tail of .
+ /// True if the vectors are collinear, false otherwise.
+ private static bool AreCollinear(Vector vector1, Vector vector2, Vector tailsVector)
+ {
+ return Math.Abs(PerpDotProduct(vector1, tailsVector)) < epsilonForComparisons &&
+ Math.Abs(PerpDotProduct(vector2, tailsVector)) < epsilonForComparisons;
+ }
+
+ private static Segment2DIntersectSegment2DResult HandleCollinearSegmentIntersection(Segment2D segment1, Segment2D segment2, Vector v, Vector w)
+ {
+ double t0, t1;
+ Vector w2 = segment1.SecondPoint - segment2.FirstPoint;
+ if (v[0] != 0.0)
+ {
+ t0 = w[0] / v[0];
+ t1 = w2[0] / v[0];
+ }
+ else
+ {
+ t0 = w[1] / v[1];
+ t1 = w2[1] / v[1];
+ }
+ // Require t0 to be smaller than t1, swapping if needed:
+ if (t0 > t1)
+ {
+ double tempSwapVariable = t0;
+ t0 = t1;
+ t1 = tempSwapVariable;
+ }
+ if (t0 > 1.0 || t1 < 0.0)
+ {
+ // There is no overlap:
+ return Segment2DIntersectSegment2DResult.CreateNoIntersectResult();
+ }
+
+ t0 = t0 < 0.0 ? 0.0 : t0; // Clip to minimum 0
+ t1 = t1 > 1.0 ? 1.0 : t1; // Clip to maximum 1
+ Point2D intersectionPoint1 = segment2.FirstPoint + v.Multiply(t0);
+ if (Math.Abs(t0 - t1) < epsilonForComparisons)
+ {
+ // Segments intersect at a point:
+ return Segment2DIntersectSegment2DResult.CreateIntersectionResult(intersectionPoint1);
+ }
+ else
+ {
+ // Segments overlap:
+ Point2D intersectionPoint2 = segment2.FirstPoint + v.Multiply(t1);
+ return Segment2DIntersectSegment2DResult.CreateOverlapResult(intersectionPoint1, intersectionPoint2);
+ }
+ }
+
+ private static bool IsSegmentAsPointIntersectionDegenerateScenario(Segment2D segment1, Segment2D segment2)
+ {
+ return IsSegmentActuallyPointDegenerate(segment1) || IsSegmentActuallyPointDegenerate(segment2);
+ }
+
+ private static bool IsSegmentActuallyPointDegenerate(Segment2D segment)
+ {
+ return segment.Length < epsilonForComparisons;
+ }
+
+ private static Segment2DIntersectSegment2DResult HandleSegmentAsPointIntersectionDegenerates(Segment2D segment1, Segment2D segment2)
+ {
+ bool segment1IsPointDegenerate = IsSegmentActuallyPointDegenerate(segment1);
+ bool segment2IsPointDegenerate = IsSegmentActuallyPointDegenerate(segment2);
+
+ if (segment1IsPointDegenerate)
+ {
+ if (segment2IsPointDegenerate)
+ {
+ // Both segments can be considered Point2D
+ return segment1.FirstPoint.Equals(segment2.FirstPoint) ?
+ Segment2DIntersectSegment2DResult.CreateIntersectionResult(segment1.FirstPoint) :
+ Segment2DIntersectSegment2DResult.CreateNoIntersectResult();
+ }
+ {
+ return IsPointInCollinearSegment(segment1.FirstPoint, segment2) ?
+ Segment2DIntersectSegment2DResult.CreateIntersectionResult(segment1.FirstPoint) :
+ Segment2DIntersectSegment2DResult.CreateNoIntersectResult();
+ }
+
+ }
+
+ return IsPointInCollinearSegment(segment2.FirstPoint, segment1) ?
+ Segment2DIntersectSegment2DResult.CreateIntersectionResult(segment2.FirstPoint) :
+ Segment2DIntersectSegment2DResult.CreateNoIntersectResult();
+ }
+
+ private static bool IsPointInCollinearSegment(Point2D point, Segment2D colinearSegment)
+ {
+ if (colinearSegment.IsVertical())
+ {
+ double minY = Math.Min(colinearSegment.FirstPoint.Y, colinearSegment.SecondPoint.Y);
+ double maxY = Math.Max(colinearSegment.FirstPoint.Y, colinearSegment.SecondPoint.Y);
+ return minY <= point.Y && point.Y <= maxY;
+ }
+ else
+ {
+ double minX = Math.Min(colinearSegment.FirstPoint.X, colinearSegment.SecondPoint.X);
+ double maxX = Math.Max(colinearSegment.FirstPoint.X, colinearSegment.SecondPoint.X);
+ return minX <= point.X && point.X <= maxX;
+ }
+ }
+
+ ///
+ /// Gets the intersection point.
+ ///
+ /// The segment1.
+ /// The segment2.
+ ///
+ /// Implementation from http://geomalgorithms.com/a05-_intersect-1.html
+ /// based on method intersect2D_2Segments.
private static Point2D GetIntersectionPoint(Segment2D segment1, Segment2D segment2)
{
var aLine = (segment1.FirstPoint.Y - segment2.FirstPoint.Y)*(segment2.SecondPoint.X - segment2.FirstPoint.X) - (segment1.FirstPoint.X - segment2.FirstPoint.X)*(segment2.SecondPoint.Y - segment2.FirstPoint.Y);
@@ -251,6 +425,33 @@
return null;
}
+ ///
+ /// Performs the dot product between a vector and a perpendicularized vector.
+ ///
+ /// The vector.
+ /// The vector that will be made perpendicular before doing
+ /// the dot product operation.
+ /// The dot product between a vector and a perpendicularized vector.
+ private static double PerpDotProduct(Vector vector1, Vector vector2)
+ {
+ Vector perpendicularVectorForVector2 = ToPerpendicular(vector2);
+ return vector1.DotProduct(perpendicularVectorForVector2);
+ }
+
+ ///
+ /// Creates a new based on a vector that is perpendicular.
+ ///
+ /// The vector.
+ /// A vector of the same length as .
+ private static Vector ToPerpendicular(Vector vector)
+ {
+ return new DenseVector(new[]
+ {
+ -vector[1],
+ vector[0]
+ });
+ }
+
private static Point2D[][] SplitLineSegmentsAtLengths(Segment2D[] lineSegments, double[] lengths)
{
var splitResults = new Point2D[lengths.Length][];
@@ -310,11 +511,8 @@
private static Point2D GetInterpolatedPoint(Segment2D lineSegment, double splitDistance)
{
var interpolationFactor = splitDistance/lineSegment.Length;
- Vector segmentVector = lineSegment.SecondPoint - lineSegment.FirstPoint;
- double interpolatedX = lineSegment.FirstPoint.X + interpolationFactor*segmentVector[0];
- double interpolatedY = lineSegment.FirstPoint.Y + interpolationFactor*segmentVector[1];
-
- return new Point2D(interpolatedX, interpolatedY);
+ Vector segmentVector = lineSegment.SecondPoint - lineSegment.FirstPoint;
+ return lineSegment.FirstPoint + segmentVector.Multiply(interpolationFactor);
}
///
Index: Core/Common/src/Core.Common.Base/Geometry/Point2D.cs
===================================================================
diff -u -re04155c0cc0efa8bbd13e0a82cb8643711a2dfd6 -r1b4f4720632f9a691837fa97e777a4637b6739c8
--- Core/Common/src/Core.Common.Base/Geometry/Point2D.cs (.../Point2D.cs) (revision e04155c0cc0efa8bbd13e0a82cb8643711a2dfd6)
+++ Core/Common/src/Core.Common.Base/Geometry/Point2D.cs (.../Point2D.cs) (revision 1b4f4720632f9a691837fa97e777a4637b6739c8)
@@ -21,6 +21,9 @@
using System;
+using Core.Common.Base.Properties;
+
+using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
namespace Core.Common.Base.Geometry
@@ -58,7 +61,7 @@
/// Head of the vector.
/// Tail of the vector.
/// A 2D vector.
- public static Vector operator -(Point2D p1, Point2D p2)
+ public static Vector operator -(Point2D p1, Point2D p2)
{
var result = new DenseVector(2);
result[0] = p1.X - p2.X;
@@ -67,6 +70,29 @@
}
///
+ /// Determines the new 2D point given a point and a 2D vector.
+ ///
+ /// The point.
+ /// The 2D vector.
+ ///
+ /// A 2D point.
+ ///
+ /// When is
+ /// not a 2D vector.
+ public static Point2D operator +(Point2D point, Vector vector)
+ {
+ if (vector.Count != 2)
+ {
+ string message = string.Format(Resources.Point2D_AddVector_Vector_must_be_2D_but_has_Dimensionality_0_,
+ vector.Count);
+ throw new ArgumentException(message, "vector");
+ }
+ double x = point.X + vector[0];
+ double y = point.Y + vector[1];
+ return new Point2D(x, y);
+ }
+
+ ///
/// Gets the euclidean distance from this point to another.
///
/// The second point.
@@ -79,7 +105,7 @@
throw new ArgumentNullException("secondPoint");
}
- Vector vector = this - secondPoint;
+ Vector vector = this - secondPoint;
return Math.Sqrt(vector.DotProduct(vector));
}
Index: Core/Common/src/Core.Common.Base/Geometry/Segment2D.cs
===================================================================
diff -u -re04155c0cc0efa8bbd13e0a82cb8643711a2dfd6 -r1b4f4720632f9a691837fa97e777a4637b6739c8
--- Core/Common/src/Core.Common.Base/Geometry/Segment2D.cs (.../Segment2D.cs) (revision e04155c0cc0efa8bbd13e0a82cb8643711a2dfd6)
+++ Core/Common/src/Core.Common.Base/Geometry/Segment2D.cs (.../Segment2D.cs) (revision 1b4f4720632f9a691837fa97e777a4637b6739c8)
@@ -23,7 +23,7 @@
using Core.Common.Base.Properties;
-using MathNet.Numerics.LinearAlgebra.Double;
+using MathNet.Numerics.LinearAlgebra;
namespace Core.Common.Base.Geometry
{
@@ -108,8 +108,8 @@
throw new ArgumentNullException("point");
}
- Vector segmentVector = SecondPoint - FirstPoint; // Vector from FirstPoint to SecondPoint
- Vector orientationVector = point - FirstPoint; // Vector from FirstPoint to 'point'
+ Vector segmentVector = SecondPoint - FirstPoint; // Vector from FirstPoint to SecondPoint
+ Vector orientationVector = point - FirstPoint; // Vector from FirstPoint to 'point'
// Situation sketch, normalized along the segment:
// A : B : C
Index: Core/Common/src/Core.Common.Base/Geometry/Segment2DIntersectSegment2DResult.cs
===================================================================
diff -u
--- Core/Common/src/Core.Common.Base/Geometry/Segment2DIntersectSegment2DResult.cs (revision 0)
+++ Core/Common/src/Core.Common.Base/Geometry/Segment2DIntersectSegment2DResult.cs (revision 1b4f4720632f9a691837fa97e777a4637b6739c8)
@@ -0,0 +1,65 @@
+namespace Core.Common.Base.Geometry
+{
+ ///
+ /// Class that captures the intersection calculation result between two
+ /// instances.
+ ///
+ public class Segment2DIntersectSegment2DResult
+ {
+ private Segment2DIntersectSegment2DResult(Intersection2DType type, Point2D[] points)
+ {
+ IntersectionType = type;
+ IntersectionPoints = points;
+ }
+
+ ///
+ /// Gets the type of the intersection found.
+ ///
+ public Intersection2DType IntersectionType { get; private set; }
+
+ ///
+ /// Gets the intersection points, if any.
+ ///
+ ///
+ /// If has a value of ,
+ /// the array holds the single intersection points found.
+ /// If has a value of ,
+ /// the array holds the two points defining the overlapping area for both segments.
+ ///
+ public Point2D[] IntersectionPoints { get; private set; }
+
+ ///
+ /// Creates the calculation result for having found no intersections.
+ ///
+ public static Segment2DIntersectSegment2DResult CreateNoIntersectResult()
+ {
+ return new Segment2DIntersectSegment2DResult(Intersection2DType.NoIntersections, new Point2D[0]);
+ }
+
+ ///
+ /// Creates the calculation result for having found a single intersection.
+ ///
+ /// The intersection point.
+ public static Segment2DIntersectSegment2DResult CreateIntersectionResult(Point2D intersectionPoint)
+ {
+ return new Segment2DIntersectSegment2DResult(Intersection2DType.Intersects, new[]
+ {
+ intersectionPoint
+ });
+ }
+
+ ///
+ /// Creates the calculation result for having found an overlap between the two segments.
+ ///
+ /// The start of the overlapping segment.
+ /// The end of the overlapping segment.
+ public static Segment2DIntersectSegment2DResult CreateOverlapResult(Point2D start, Point2D end)
+ {
+ return new Segment2DIntersectSegment2DResult(Intersection2DType.Overlapping, new[]
+ {
+ start,
+ end
+ });
+ }
+ }
+}
\ No newline at end of file
Index: Core/Common/src/Core.Common.Base/Properties/Resources.Designer.cs
===================================================================
diff -u -rd36a95d2e88d98b7b92ff5d091abf711d1dd31d9 -r1b4f4720632f9a691837fa97e777a4637b6739c8
--- Core/Common/src/Core.Common.Base/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision d36a95d2e88d98b7b92ff5d091abf711d1dd31d9)
+++ Core/Common/src/Core.Common.Base/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 1b4f4720632f9a691837fa97e777a4637b6739c8)
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.17929
+// Runtime Version:4.0.30319.18444
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -152,6 +152,15 @@
}
///
+ /// Looks up a localized string similar to Vector moet 2 dimensies hebben, maar heeft er {0}..
+ ///
+ public static string Point2D_AddVector_Vector_must_be_2D_but_has_Dimensionality_0_ {
+ get {
+ return ResourceManager.GetString("Point2D_AddVector_Vector_must_be_2D_but_has_Dimensionality_0_", resourceCulture);
+ }
+ }
+
+ ///
/// Looks up a localized string similar to Project.
///
public static string Project_Constructor_Default_name {
Index: Core/Common/src/Core.Common.Base/Properties/Resources.resx
===================================================================
diff -u -rd36a95d2e88d98b7b92ff5d091abf711d1dd31d9 -r1b4f4720632f9a691837fa97e777a4637b6739c8
--- Core/Common/src/Core.Common.Base/Properties/Resources.resx (.../Resources.resx) (revision d36a95d2e88d98b7b92ff5d091abf711d1dd31d9)
+++ Core/Common/src/Core.Common.Base/Properties/Resources.resx (.../Resources.resx) (revision 1b4f4720632f9a691837fa97e777a4637b6739c8)
@@ -165,4 +165,7 @@
De tekst is een getal dat te groot of te klein is om gerepresenteerd te worden.
+
+ Vector moet 2 dimensies hebben, maar heeft er {0}.
+
\ No newline at end of file
Index: Core/Common/test/Core.Common.Base.Test/Core.Common.Base.Test.csproj
===================================================================
diff -u -r93b256575fba3e4068baadeeb62140533336371a -r1b4f4720632f9a691837fa97e777a4637b6739c8
--- Core/Common/test/Core.Common.Base.Test/Core.Common.Base.Test.csproj (.../Core.Common.Base.Test.csproj) (revision 93b256575fba3e4068baadeeb62140533336371a)
+++ Core/Common/test/Core.Common.Base.Test/Core.Common.Base.Test.csproj (.../Core.Common.Base.Test.csproj) (revision 1b4f4720632f9a691837fa97e777a4637b6739c8)
@@ -86,6 +86,7 @@
+
Index: Core/Common/test/Core.Common.Base.Test/Geometry/Math2DTest.cs
===================================================================
diff -u -rd36a95d2e88d98b7b92ff5d091abf711d1dd31d9 -r1b4f4720632f9a691837fa97e777a4637b6739c8
--- Core/Common/test/Core.Common.Base.Test/Geometry/Math2DTest.cs (.../Math2DTest.cs) (revision d36a95d2e88d98b7b92ff5d091abf711d1dd31d9)
+++ Core/Common/test/Core.Common.Base.Test/Geometry/Math2DTest.cs (.../Math2DTest.cs) (revision 1b4f4720632f9a691837fa97e777a4637b6739c8)
@@ -570,6 +570,273 @@
}
[Test]
+ [TestCase(1234.56789)]
+ [TestCase(1e-6)]
+ [TestCase(-1e-6)]
+ [TestCase(-98765.4321)]
+ public void GetIntersectionBetweenSegments_TwoHorizontalParallelSegments_ReturnNoIntersection(
+ double dy)
+ {
+ // Setup
+ const double y1 = 2.2;
+ double y2 = y1+dy;
+
+ const double x1 = 1.1;
+ const double x2 = 3.3;
+ var horizontalSegment1 = new Segment2D(new Point2D(x1, y1), new Point2D(x2, y1));
+ var horizontalSegment2 = new Segment2D(new Point2D(x1, y2), new Point2D(x2, y2));
+
+ // Call
+ Segment2DIntersectSegment2DResult result = Math2D.GetIntersectionBetweenSegments(horizontalSegment1, horizontalSegment2);
+
+ // Assert
+ Assert.AreEqual(Intersection2DType.NoIntersections, result.IntersectionType);
+ CollectionAssert.IsEmpty(result.IntersectionPoints);
+ }
+
+ [Test]
+ [TestCase(1234.56789)]
+ [TestCase(1e-6)]
+ [TestCase(-1e-6)]
+ [TestCase(-98765.4321)]
+ public void GetIntersectionBetweenSegments_TwoVerticalParallelSegments_ReturnNoIntersection(
+ double dx)
+ {
+ // Setup
+ const double x1 = 1.1;
+ double x2 = x1 + dx;
+
+ const double y1 = 2.2;
+ const double y2 = 3.3;
+ var horizontalSegment1 = new Segment2D(new Point2D(x1, y1), new Point2D(x1, y2));
+ var horizontalSegment2 = new Segment2D(new Point2D(x2, y1), new Point2D(x2, y2));
+
+ // Call
+ Segment2DIntersectSegment2DResult result = Math2D.GetIntersectionBetweenSegments(horizontalSegment1, horizontalSegment2);
+
+ // Assert
+ Assert.AreEqual(Intersection2DType.NoIntersections, result.IntersectionType);
+ CollectionAssert.IsEmpty(result.IntersectionPoints);
+ }
+
+ [Test]
+ public void GetIntersectionBetweenSegments_TwoParallelSegments_ReturnNoIntersection()
+ {
+ // Setup
+ var segment1 = new Segment2D(new Point2D(1.1, 3.3), new Point2D(2.2, 4.4));
+ var segment2 = new Segment2D(new Point2D(1.1, 5.5), new Point2D(2.2, 6.6));
+
+ // Call
+ Segment2DIntersectSegment2DResult result = Math2D.GetIntersectionBetweenSegments(segment1, segment2);
+
+ // Assert
+ Assert.AreEqual(Intersection2DType.NoIntersections, result.IntersectionType);
+ CollectionAssert.IsEmpty(result.IntersectionPoints);
+ }
+
+ [Test]
+ [TestCase(12.34)]
+ [TestCase(1.1 + 1e-6)]
+ [TestCase(-1.1 - 1e-6)]
+ [TestCase(-56.78)]
+ public void GetIntersectionBetweenSegments_TwoCollinearHorizontalLinesWithoutOverlap_ReturnNoIntersection(double dy)
+ {
+ // Setup
+ const double x1 = 1.1;
+ const double x2 = 2.2;
+ const double y = 3.3;
+
+ double x3 = x1 + dy;
+ double x4 = x2 + dy;
+ var horizontalSegment1 = new Segment2D(new Point2D(x1, y), new Point2D(x2, y));
+ var horizontalSegment2 = new Segment2D(new Point2D(x3, y), new Point2D(x4, y));
+
+ // Call
+ Segment2DIntersectSegment2DResult result = Math2D.GetIntersectionBetweenSegments(horizontalSegment1, horizontalSegment2);
+
+ // Assert
+ Assert.AreEqual(Intersection2DType.NoIntersections, result.IntersectionType);
+ CollectionAssert.IsEmpty(result.IntersectionPoints);
+ }
+
+ [Test]
+ [TestCase(12.34)]
+ [TestCase(3.3 + 1e-6)]
+ [TestCase(-3.3 - 1e-6)]
+ [TestCase(-56.78)]
+ public void GetIntersectionBetweenSegments_TwoCollinearVerticalLinesWithoutOverlap_ReturnNoIntersection(double dy)
+ {
+ // Setup
+ const double y1 = 1.1;
+ const double y2 = 4.4;
+ const double x = 3.3;
+
+ double y3 = y2 + dy;
+ double y4 = y1 + dy;
+ var horizontalSegment1 = new Segment2D(new Point2D(x, y1), new Point2D(x, y2));
+ var horizontalSegment2 = new Segment2D(new Point2D(x, y3), new Point2D(x, y4));
+
+ // Call
+ Segment2DIntersectSegment2DResult result = Math2D.GetIntersectionBetweenSegments(horizontalSegment1, horizontalSegment2);
+
+ // Assert
+ Assert.AreEqual(Intersection2DType.NoIntersections, result.IntersectionType);
+ CollectionAssert.IsEmpty(result.IntersectionPoints);
+ }
+
+ [Test]
+ [TestCase(-3.3)]
+ [TestCase(7.7)]
+ public void GetIntersectionBetweenSegments_TwoCollinearSegmentsWithoutOverlap_ReturnNoIntersection(
+ double dx)
+ {
+ // Setup
+ Func getY = x => 1.1 * x + 2.2;
+ const double x1 = 1.1;
+ const double x2 = 3.3;
+ var segment1 = new Segment2D(new Point2D(x1, getY(x1)), new Point2D(x2, getY(x2)));
+
+ double x3 = x1 + dx;
+ double x4 = x2 + dx;
+ var segment2 = new Segment2D(new Point2D(x3, getY(x3)), new Point2D(x4, getY(x4)));
+
+ // Call
+ Segment2DIntersectSegment2DResult result = Math2D.GetIntersectionBetweenSegments(segment1, segment2);
+
+ // Assert
+ Assert.AreEqual(Intersection2DType.NoIntersections, result.IntersectionType);
+ CollectionAssert.IsEmpty(result.IntersectionPoints);
+ }
+
+ [Test]
+ [TestCase(0)]
+ [TestCase(1)]
+ [TestCase(2)]
+ [TestCase(3)]
+ public void GetIntersectionBetweenSegments_TwoCollinearHorizontalSegmentsConnectedAtSegmentEnds_ReturnIntersectionPoint(
+ int configurationNumber)
+ {
+ // Setup
+ const double y = -6.7;
+ var segment1UniquePoint = new Point2D(-12.34, y);
+ var segmentCommonPoint = new Point2D(56.78, y);
+ var segment2UniquePoint = new Point2D(91.23, y);
+
+ Segment2D horizontalSegment1, horizontalSegment2;
+ if (configurationNumber == 0 || configurationNumber == 3)
+ {
+ horizontalSegment1 = new Segment2D(segment1UniquePoint, segmentCommonPoint);
+ }
+ else
+ {
+ horizontalSegment1 = new Segment2D(segmentCommonPoint, segment1UniquePoint);
+ }
+
+ if (configurationNumber == 0 || configurationNumber == 1)
+ {
+ horizontalSegment2 = new Segment2D(segment2UniquePoint, segmentCommonPoint);
+ }
+ else
+ {
+ horizontalSegment2 = new Segment2D(segmentCommonPoint, segment2UniquePoint);
+ }
+
+ // Call
+ Segment2DIntersectSegment2DResult result = Math2D.GetIntersectionBetweenSegments(horizontalSegment1, horizontalSegment2);
+
+ // Assert
+ Assert.AreEqual(Intersection2DType.Intersects, result.IntersectionType);
+ CollectionAssert.AreEqual(new[] { segmentCommonPoint }, result.IntersectionPoints);
+ }
+
+ [Test]
+ [TestCase(0)]
+ [TestCase(1)]
+ [TestCase(2)]
+ [TestCase(3)]
+ public void GetIntersectionBetweenSegments_TwoCollinearVerticalSegmentsConnectedAtSegmentEnds_ReturnIntersectionPoint(
+ int configurationNumber)
+ {
+ // Setup
+ const double x = 5.5;
+ var segment1UniquePoint = new Point2D(x, -23.45);
+ var segmentCommonPoint = new Point2D(x, -12.34);
+ var segment2UniquePoint = new Point2D(x, 90.76);
+
+ Segment2D verticalSegment1, verticalSegment2;
+ if (configurationNumber == 0 || configurationNumber == 3)
+ {
+ verticalSegment1 = new Segment2D(segment1UniquePoint, segmentCommonPoint);
+ }
+ else
+ {
+ verticalSegment1 = new Segment2D(segmentCommonPoint, segment1UniquePoint);
+ }
+
+ if (configurationNumber == 0 || configurationNumber == 1)
+ {
+ verticalSegment2 = new Segment2D(segment2UniquePoint, segmentCommonPoint);
+ }
+ else
+ {
+ verticalSegment2 = new Segment2D(segmentCommonPoint, segment2UniquePoint);
+ }
+
+ // Call
+ Segment2DIntersectSegment2DResult result = Math2D.GetIntersectionBetweenSegments(verticalSegment1, verticalSegment2);
+
+ // Assert
+ Assert.AreEqual(Intersection2DType.Intersects, result.IntersectionType);
+ CollectionAssert.AreEqual(new[] { segmentCommonPoint }, result.IntersectionPoints,
+ new Point2DComparerWithTolerance(1e-6));
+ }
+
+ [Test]
+ [TestCase(0)]
+ [TestCase(1)]
+ [TestCase(2)]
+ [TestCase(3)]
+ public void GetIntersectionBetweenSegments_TwoCollinearSegmentsConnectedAtSegmentEnds_ReturnIntersectionPoint(
+ int configurationNumber)
+ {
+ // Setup
+ Func getY = x => 3.3 * x + 4.4;
+
+ const double x1 = 5.5;
+ const double x2 = 6.6;
+ const double x3 = 8.8;
+ var segment1UniquePoint = new Point2D(x1, getY(x1));
+ var segmentCommonPoint = new Point2D(x2, getY(x2));
+ var segment2UniquePoint = new Point2D(x3, getY(x3));
+
+ Segment2D segment1, segment2;
+ if (configurationNumber == 0 || configurationNumber == 3)
+ {
+ segment1 = new Segment2D(segment1UniquePoint, segmentCommonPoint);
+ }
+ else
+ {
+ segment1 = new Segment2D(segmentCommonPoint, segment1UniquePoint);
+ }
+
+ if (configurationNumber == 0 || configurationNumber == 1)
+ {
+ segment2 = new Segment2D(segment2UniquePoint, segmentCommonPoint);
+ }
+ else
+ {
+ segment2 = new Segment2D(segmentCommonPoint, segment2UniquePoint);
+ }
+
+ // Call
+ Segment2DIntersectSegment2DResult result = Math2D.GetIntersectionBetweenSegments(segment1, segment2);
+
+ // Assert
+ Assert.AreEqual(Intersection2DType.Intersects, result.IntersectionType);
+ CollectionAssert.AreEqual(new[]{segmentCommonPoint}, result.IntersectionPoints);
+ }
+
+ [Test]
public void AreEqualPoints_PointsEqual_ReturnsTrue()
{
// Call
Index: Core/Common/test/Core.Common.Base.Test/Geometry/Point2DTest.cs
===================================================================
diff -u -re04155c0cc0efa8bbd13e0a82cb8643711a2dfd6 -r1b4f4720632f9a691837fa97e777a4637b6739c8
--- Core/Common/test/Core.Common.Base.Test/Geometry/Point2DTest.cs (.../Point2DTest.cs) (revision e04155c0cc0efa8bbd13e0a82cb8643711a2dfd6)
+++ Core/Common/test/Core.Common.Base.Test/Geometry/Point2DTest.cs (.../Point2DTest.cs) (revision 1b4f4720632f9a691837fa97e777a4637b6739c8)
@@ -22,7 +22,9 @@
using System;
using Core.Common.Base.Geometry;
+using Core.Common.TestUtil;
+using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using NUnit.Framework;
@@ -164,7 +166,7 @@
var point2 = new Point2D(1.0, 1.0);
// Call
- Vector vector = point1 - point2;
+ Vector vector = point1 - point2;
// Assert
Assert.AreEqual(2, vector.Count);
@@ -173,6 +175,61 @@
}
[Test]
+ public void AddOperator_PointWithZeroVector_ReturnEqualPoint(
+ [Random(-12345.6789, 9876.54321, 1)]double x,
+ [Random(-12345.6789, 9876.54321, 1)]double y)
+ {
+ // Setup
+ var originalPoint = new Point2D(x, y);
+ var zeroVector = new DenseVector(new []{ 0.0, 0.0 });
+
+ // Call
+ Point2D resultPoint = originalPoint + zeroVector;
+
+ // Assert
+ Assert.AreNotSame(originalPoint, resultPoint);
+ Assert.AreEqual(x, resultPoint.X);
+ Assert.AreEqual(y, resultPoint.Y);
+ }
+
+ [Test]
+ public void AddOperator_PointWithVector_ReturnEqualPoint(
+ [Random(-12345.6789, 98765.4321, 1)]double x,
+ [Random(-12345.6789, 98765.4321, 1)]double y)
+ {
+ // Setup
+ var originalPoint = new Point2D(x, y);
+ const double dx = 1.1;
+ const double dy = -2.2;
+ var vector = new DenseVector(new[] { dx, dy });
+
+ // Call
+ Point2D resultPoint = originalPoint + vector;
+
+ // Assert
+ Assert.AreEqual(x+dx, resultPoint.X);
+ Assert.AreEqual(y+dy, resultPoint.Y);
+ }
+
+ [Test]
+ public void AddOperator_PointWithInvalidVector_ThrowArgumentException()
+ {
+ // Setup
+ var originalPoint = new Point2D(0.0, 0.0);
+ var vector3D = new DenseVector(new []{1.1, 2.2, 3.3});
+
+ // Call
+ TestDelegate call = () =>
+ {
+ Point2D result = originalPoint + vector3D;
+ };
+
+ // Assert
+ const string expectedMessage = "Vector moet 2 dimensies hebben, maar heeft er 3.";
+ TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage);
+ }
+
+ [Test]
public void GetEuclideanDistanceTo_Itself_ReturnZero()
{
// Setup
Index: Core/Common/test/Core.Common.Base.Test/Geometry/Segment2DIntersectSegment2DResultTest.cs
===================================================================
diff -u
--- Core/Common/test/Core.Common.Base.Test/Geometry/Segment2DIntersectSegment2DResultTest.cs (revision 0)
+++ Core/Common/test/Core.Common.Base.Test/Geometry/Segment2DIntersectSegment2DResultTest.cs (revision 1b4f4720632f9a691837fa97e777a4637b6739c8)
@@ -0,0 +1,50 @@
+using Core.Common.Base.Geometry;
+
+using NUnit.Framework;
+
+namespace Core.Common.Base.Test.Geometry
+{
+ [TestFixture]
+ public class Segment2DIntersectSegment2DResultTest
+ {
+ [Test]
+ public void CreateNoIntersectResult_ExpectedValues()
+ {
+ // Call
+ Segment2DIntersectSegment2DResult result = Segment2DIntersectSegment2DResult.CreateNoIntersectResult();
+
+ // Assert
+ Assert.AreEqual(Intersection2DType.NoIntersections, result.IntersectionType);
+ CollectionAssert.IsEmpty(result.IntersectionPoints);
+ }
+
+ [Test]
+ public void CreateIntersectionResult_ExpectedValues()
+ {
+ // Setup
+ var point = new Point2D(1.1, 2.2);
+
+ // Call
+ Segment2DIntersectSegment2DResult result = Segment2DIntersectSegment2DResult.CreateIntersectionResult(point);
+
+ // Assert
+ Assert.AreEqual(Intersection2DType.Intersects, result.IntersectionType);
+ CollectionAssert.AreEqual(new[]{point}, result.IntersectionPoints);
+ }
+
+ [Test]
+ public void CreateOverlapResult_ExpectedValues()
+ {
+ // Setup
+ var point1 = new Point2D(1.1, 2.2);
+ var point2 = new Point2D(1.1, 2.2);
+
+ // Call
+ Segment2DIntersectSegment2DResult result = Segment2DIntersectSegment2DResult.CreateOverlapResult(point1, point2);
+
+ // Assert
+ Assert.AreEqual(Intersection2DType.Overlapping, result.IntersectionType);
+ CollectionAssert.AreEqual(new[] { point1, point2 }, result.IntersectionPoints);
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Piping/src/Ringtoets.Piping.Primitives/RingtoetsPipingSurfaceLine.cs
===================================================================
diff -u -r10779bb6a6db2d00f4627b2bc190e7e35e1fee3e -r1b4f4720632f9a691837fa97e777a4637b6739c8
--- Ringtoets/Piping/src/Ringtoets.Piping.Primitives/RingtoetsPipingSurfaceLine.cs (.../RingtoetsPipingSurfaceLine.cs) (revision 10779bb6a6db2d00f4627b2bc190e7e35e1fee3e)
+++ Ringtoets/Piping/src/Ringtoets.Piping.Primitives/RingtoetsPipingSurfaceLine.cs (.../RingtoetsPipingSurfaceLine.cs) (revision 1b4f4720632f9a691837fa97e777a4637b6739c8)
@@ -24,7 +24,8 @@
using System.Collections.ObjectModel;
using System.Linq;
using Core.Common.Base.Geometry;
-using MathNet.Numerics.LinearAlgebra.Double;
+
+using MathNet.Numerics.LinearAlgebra;
using Ringtoets.Piping.Primitives.Exceptions;
using Ringtoets.Piping.Primitives.Properties;
@@ -371,14 +372,14 @@
// Determine the vectors from the first coordinate to each other coordinate point
// in the XY world coordinate plane:
Point2D[] worldCoordinates = Points.Select(p => new Point2D(p.X, p.Y)).ToArray();
- var worldCoordinateVectors = new Vector[worldCoordinates.Length - 1];
+ var worldCoordinateVectors = new Vector[worldCoordinates.Length - 1];
for (int i = 1; i < worldCoordinates.Length; i++)
{
worldCoordinateVectors[i - 1] = worldCoordinates[i] - worldCoordinates[0];
}
// Determine the 'spanning line' vector:
- Vector spanningVector = worldCoordinateVectors[worldCoordinateVectors.Length - 1];
+ Vector spanningVector = worldCoordinateVectors[worldCoordinateVectors.Length - 1];
double spanningVectorDotProduct = spanningVector.DotProduct(spanningVector);
double length = Math.Sqrt(spanningVectorDotProduct);