Index: Core/Common/src/Core.Common.Base/Core.Common.Base.csproj =================================================================== diff -u -rfcc49aac894f989182fb9faa487e50a585fbed03 -rdaf4bf00e8ea376485f54faa2fee8497607ddfb0 --- Core/Common/src/Core.Common.Base/Core.Common.Base.csproj (.../Core.Common.Base.csproj) (revision fcc49aac894f989182fb9faa487e50a585fbed03) +++ Core/Common/src/Core.Common.Base/Core.Common.Base.csproj (.../Core.Common.Base.csproj) (revision daf4bf00e8ea376485f54faa2fee8497607ddfb0) @@ -87,6 +87,7 @@ Properties\GlobalAssembly.cs + Index: Core/Common/src/Core.Common.Base/Geometry/Math2D.cs =================================================================== diff -u --- Core/Common/src/Core.Common.Base/Geometry/Math2D.cs (revision 0) +++ Core/Common/src/Core.Common.Base/Geometry/Math2D.cs (revision daf4bf00e8ea376485f54faa2fee8497607ddfb0) @@ -0,0 +1,140 @@ +// Copyright (C) Stichting Deltares 2016. All rights reserved. +// +// This file is part of Ringtoets. +// +// Ringtoets is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +using Core.Common.Base.Properties; + +namespace Core.Common.Base.Geometry +{ + /// + /// 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; + } + + var x = (bOtherLine*cLine - bLine*cOtherLine)/determinant; + var y = (aLine*cOtherLine - aOtherLine*cLine)/determinant; + return new Point2D(x, y); + } + + /// + /// Determines the intersection points of a of with a vertical line + /// which is plotted at x=. + /// + /// A collection of segments that possibly intersect with the + /// vertical line at x=. + /// The x coordinate of the vertical line. + /// A of with all intersection points of the + /// with the vertical line at x=. + /// Segments which have length=0 or which are vertical, will not return an intersection point. + public static IEnumerable SegmentsIntersectionWithVerticalLine(IEnumerable segments, double verticalLineX) + { + var intersectionPointY = new Collection(); + + foreach (Segment2D segment in segments.Where(s => s.ContainsX(verticalLineX))) + { + Point2D intersectionPoint = LineIntersectionWithVerticalLine(segment.FirstPoint, segment.SecondPoint, verticalLineX); + + if (intersectionPoint != null) + { + intersectionPointY.Add(intersectionPoint); + } + } + + return intersectionPointY; + } + + /// + /// Determines the intersection point of a line through the points and + /// with a vertical line at x=. If + /// equals , then no intersection point + /// will be returned. + /// + /// A which the line passes through. + /// Another which the line passes through. + /// The x coordinate of the vertical line. + /// The intersection point between the line through and + /// and the vertical line at x=; or null if + /// the line through and is vertical or + /// the points are equal. + private static Point2D LineIntersectionWithVerticalLine(Point2D point1, Point2D point2, double x) + { + var verticalLineFirstPoint = new Point2D(x, 0); + var verticalLineSecondPoint = new Point2D(x, 1); + + try + { + return LineIntersectionWithLine(point1, point2, verticalLineFirstPoint, verticalLineSecondPoint); + } + catch (ArgumentException) + { + return null; + } + } + } +} \ No newline at end of file Index: Core/Common/src/Core.Common.Base/Properties/Resources.Designer.cs =================================================================== diff -u -rfcc49aac894f989182fb9faa487e50a585fbed03 -rdaf4bf00e8ea376485f54faa2fee8497607ddfb0 --- Core/Common/src/Core.Common.Base/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision fcc49aac894f989182fb9faa487e50a585fbed03) +++ Core/Common/src/Core.Common.Base/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision daf4bf00e8ea376485f54faa2fee8497607ddfb0) @@ -116,6 +116,15 @@ } /// + /// Looks up a localized string similar to Punten voor een lijn moeten uit elkaar liggen om een lijn te kunnen vormen.. + /// + public static string Math2D_LineIntersectionWithLine_Line_points_are_equal { + get { + return ResourceManager.GetString("Math2D_LineIntersectionWithLine_Line_points_are_equal", 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 -rfcc49aac894f989182fb9faa487e50a585fbed03 -rdaf4bf00e8ea376485f54faa2fee8497607ddfb0 --- Core/Common/src/Core.Common.Base/Properties/Resources.resx (.../Resources.resx) (revision fcc49aac894f989182fb9faa487e50a585fbed03) +++ Core/Common/src/Core.Common.Base/Properties/Resources.resx (.../Resources.resx) (revision daf4bf00e8ea376485f54faa2fee8497607ddfb0) @@ -141,4 +141,7 @@ Voor het maken van een segment zijn twee punten nodig. + + Punten voor een lijn moeten uit elkaar liggen om een lijn te kunnen vormen. + \ No newline at end of file Index: Core/Common/test/Core.Common.Base.Test/Core.Common.Base.Test.csproj =================================================================== diff -u -rfcc49aac894f989182fb9faa487e50a585fbed03 -rdaf4bf00e8ea376485f54faa2fee8497607ddfb0 --- Core/Common/test/Core.Common.Base.Test/Core.Common.Base.Test.csproj (.../Core.Common.Base.Test.csproj) (revision fcc49aac894f989182fb9faa487e50a585fbed03) +++ Core/Common/test/Core.Common.Base.Test/Core.Common.Base.Test.csproj (.../Core.Common.Base.Test.csproj) (revision daf4bf00e8ea376485f54faa2fee8497607ddfb0) @@ -82,6 +82,7 @@ + Index: Core/Common/test/Core.Common.Base.Test/Geometry/Math2DTest.cs =================================================================== diff -u --- Core/Common/test/Core.Common.Base.Test/Geometry/Math2DTest.cs (revision 0) +++ Core/Common/test/Core.Common.Base.Test/Geometry/Math2DTest.cs (revision daf4bf00e8ea376485f54faa2fee8497607ddfb0) @@ -0,0 +1,210 @@ +using System; +using System.Collections; +using System.Linq; + +using Core.Common.Base.Geometry; + +using NUnit.Framework; + +namespace Core.Common.Base.Test.Geometry +{ + [TestFixture] + public class Math2DTest + { + #region testcases + + /// + /// Test cases for intersecting segments. The contains pairs of , + /// which represent the coordinate of a point. Each pair of coordinates form a segment. + /// The last 2 double values are the expected intersection points. + /// + private static IEnumerable IntersectingSegments() + { + // \/ + // /\ + var testCaseDatadata1 = new TestCaseData(new[] + { + new Point2D(0.0,0.0), + new Point2D(1.0,1.0), + new Point2D(1.0,0.0), + new Point2D(0.0,1.0), + new Point2D(0.5,0.5) + }, "IntersectingSegments 1"); + yield return testCaseDatadata1; + + // __ + // / + // / + var testCaseDatadata2 = new TestCaseData(new[] + { + new Point2D(0.0,0.0), + new Point2D(1.0,1.0), + new Point2D(0.0,1.0), + new Point2D(1.0,1.0), + new Point2D(1.0,1.0) + }, "IntersectingSegments 2"); + yield return testCaseDatadata2; + + // + // / + // /__ + var testCaseDatadata3 = new TestCaseData(new[] + { + new Point2D(0.0,0.0), + new Point2D(1.0,0.0), + new Point2D(0.0,0.0), + new Point2D(1.0,1.0), + new Point2D(0.0,0.0) + }, "IntersectingSegments 3"); + yield return testCaseDatadata3; + } + + /// + /// Test cases for parallel segments. The contains pairs of , + /// which represent the coordinate of a point. Each pair of coordinates form a segment. + /// + private static IEnumerable ParallelSegments() + { + + // __ + // __ + var testCaseDatadata1 = new TestCaseData(new[] + { + new Point2D(0.0, 0.0), + new Point2D(1.0, 0.0), + new Point2D(0.0, 1.0), + new Point2D(1.0, 1.0) + }, "ParallelSegments"); + yield return testCaseDatadata1; + + + // ____ (connected in single point) + var testCaseDatadata2 = new TestCaseData(new[] + { + new Point2D(0.0, 0.0), + new Point2D(1.0, 0.0), + new Point2D(1.0, 0.0), + new Point2D(2.0, 0.0) + }, "ParallelSegments, connected in single point"); + yield return testCaseDatadata2; + + + // __ (overlap) + var testCaseDatadata3 = new TestCaseData(new[] + { + new Point2D(0.0, 0.0), + new Point2D(1.0, 0.0), + new Point2D(0.5, 0.0), + new Point2D(1.5, 0.0) + }, "ParallelSegments, overlap"); + yield return testCaseDatadata3; + } + + /// + /// Test cases for non intersecting segments. The contains pairs of , + /// which represent the coordinate of a point. Each pair of coordinates form a segment. + /// + private static readonly Point2D[][] NonIntersectingSegments = + { + // | + // ___ + new[] + { + new Point2D(0.0,0.0), + new Point2D(1.0,0.0), + new Point2D(0.5,1.0), + new Point2D(0.5,0.5), + new Point2D(0.5,0.0) + } + }; + + #endregion + + [Test] + [TestCaseSource("IntersectingSegments")] + public void LineIntersectionWithLine_DifferentLineSegmentsWithIntersections_ReturnsPoint(Point2D[] points, string testname = "") + { + // Call + var result = Math2D.LineIntersectionWithLine(points[0], points[1], points[2], points[3]); + + // Assert + Assert.AreEqual(points[4], result); + } + + [Test] + [TestCaseSource("ParallelSegments")] + // String testname was added because the Teamcity report only counts the unique signatures that were tested + public void LineIntersectionWithLine_DifferentParallelLineSegments_ReturnsNoPoint(Point2D[] points, string testname="") + { + // Call + var result = Math2D.LineIntersectionWithLine(points[0], points[1], points[2], points[3]); + + // Assert + Assert.IsNull(result); + } + + [Test] + [TestCaseSource("NonIntersectingSegments")] + public void LineIntersectionWithLine_DifferentLineSegmentsWithNoIntersection_ReturnsPoint(Point2D[] points) + { + // Call + var result = Math2D.LineIntersectionWithLine(points[0], points[1], points[2], points[3]); + + // Assert + Assert.AreEqual(points[4], result); + } + + [Test] + public void LineIntersectionWithLine_WithEqualPoints_ThrowsArgumentException() + { + // Call + TestDelegate testA = () => Math2D.LineIntersectionWithLine(new Point2D(0,0), new Point2D(0,0), new Point2D(1,0), new Point2D(0,1)); + TestDelegate testB = () => Math2D.LineIntersectionWithLine(new Point2D(0, 1), new Point2D(0, 0), new Point2D(1, 1), new Point2D(1, 1)); + + // Assert + var exceptionA = Assert.Throws(testA); + var exceptionB = Assert.Throws(testB); + Assert.AreEqual(Properties.Resources.Math2D_LineIntersectionWithLine_Line_points_are_equal, exceptionA.Message); + Assert.AreEqual(Properties.Resources.Math2D_LineIntersectionWithLine_Line_points_are_equal,exceptionB.Message); + } + + [Test] + public void LineIntersectionWithLine_InterSectionsHigherUpX_ReturnsIntersectionWithTolerance() + { + // Setup + var y1 = 5.925; + var y2 = 5.890; + var start = 133; + + // Call + var result = Math2D.LineIntersectionWithLine(new Point2D(start, y1), new Point2D(start + 1, y2), new Point2D(start + 0.5, 0), new Point2D(start + 0.5, 1)); + + // Assert + Assert.AreEqual((y1+y2)/2, result.Y, 1e-8); + } + + [Test] + [TestCase(2.5, new [] {3.3})] + [TestCase(1.1, new double[0])] + [TestCase(5.5, new double[0])] + [TestCase(-1.5, new []{1.5, 3.75})] + public void SegmentsIntersectionWithVerticalLine_SegmentsCollectionNotIntersecting_ReturnsEmptyCollection(double x, double[] intersectionHeights) + { + // Setup + var segments = new[] + { + new Segment2D(new Point2D(2.2,3.3), new Point2D(3.3,3.3)), + new Segment2D(new Point2D(1.1,5.0), new Point2D(1.1,2.0)), // vertical + new Segment2D(new Point2D(5.5,2.0), new Point2D(5.5,2.0)), // no length + new Segment2D(new Point2D(-2.0,1.0), new Point2D(-1.0,2.0)), + new Segment2D(new Point2D(-1.0,2.0), new Point2D(-2.0,5.5)) + }; + + // Call + var result = Math2D.SegmentsIntersectionWithVerticalLine(segments, x); + + // Assert + Assert.AreEqual(intersectionHeights.Select(y => new Point2D(x, y)), result); + } + } +} \ No newline at end of file Fisheye: Tag daf4bf00e8ea376485f54faa2fee8497607ddfb0 refers to a dead (removed) revision in file `Ringtoets/Piping/src/Ringtoets.Piping.Data/Calculation/Math2D.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/Properties/Resources.Designer.cs =================================================================== diff -u -r1ce62a05fe624df22af3f1d83288457ec163dabc -rdaf4bf00e8ea376485f54faa2fee8497607ddfb0 --- Ringtoets/Piping/src/Ringtoets.Piping.Data/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 1ce62a05fe624df22af3f1d83288457ec163dabc) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision daf4bf00e8ea376485f54faa2fee8497607ddfb0) @@ -178,15 +178,6 @@ } /// - /// Looks up a localized string similar to Punten voor een lijn moeten uit elkaar liggen om een lijn te kunnen vormen.. - /// - public static string Math2D_LineIntersectionWithLine_Line_points_are_equal { - get { - return ResourceManager.GetString("Math2D_LineIntersectionWithLine_Line_points_are_equal", resourceCulture); - } - } - - /// /// Looks up a localized string similar to Nieuwe berekening. /// public static string PipingCalculation_DefaultName { Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/Properties/Resources.resx =================================================================== diff -u -r1ce62a05fe624df22af3f1d83288457ec163dabc -rdaf4bf00e8ea376485f54faa2fee8497607ddfb0 --- Ringtoets/Piping/src/Ringtoets.Piping.Data/Properties/Resources.resx (.../Resources.resx) (revision 1ce62a05fe624df22af3f1d83288457ec163dabc) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/Properties/Resources.resx (.../Resources.resx) (revision daf4bf00e8ea376485f54faa2fee8497607ddfb0) @@ -135,9 +135,6 @@ Gemiddelde moet groter zijn dan 0. - - Punten voor een lijn moeten uit elkaar liggen om een lijn te kunnen vormen. - Kan geen hoogte bepalen op het punt L={0}, omdat de profielmeting verticaal loopt op dat punt. Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/Ringtoets.Piping.Data.csproj =================================================================== diff -u -rfcc49aac894f989182fb9faa487e50a585fbed03 -rdaf4bf00e8ea376485f54faa2fee8497607ddfb0 --- Ringtoets/Piping/src/Ringtoets.Piping.Data/Ringtoets.Piping.Data.csproj (.../Ringtoets.Piping.Data.csproj) (revision fcc49aac894f989182fb9faa487e50a585fbed03) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/Ringtoets.Piping.Data.csproj (.../Ringtoets.Piping.Data.csproj) (revision daf4bf00e8ea376485f54faa2fee8497607ddfb0) @@ -53,7 +53,6 @@ Properties\GlobalAssembly.cs - Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/RingtoetsPipingSurfaceLine.cs =================================================================== diff -u -r82c08997cab1058c739a21c9339e4fef59ee58ff -rdaf4bf00e8ea376485f54faa2fee8497607ddfb0 --- Ringtoets/Piping/src/Ringtoets.Piping.Data/RingtoetsPipingSurfaceLine.cs (.../RingtoetsPipingSurfaceLine.cs) (revision 82c08997cab1058c739a21c9339e4fef59ee58ff) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/RingtoetsPipingSurfaceLine.cs (.../RingtoetsPipingSurfaceLine.cs) (revision daf4bf00e8ea376485f54faa2fee8497607ddfb0) @@ -25,7 +25,7 @@ using System.Linq; using Core.Common.Base.Geometry; using MathNet.Numerics.LinearAlgebra.Double; -using Ringtoets.Piping.Data.Calculation; + using Ringtoets.Piping.Data.Exceptions; using Ringtoets.Piping.Data.Properties; Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2D.cs =================================================================== diff -u -rfcc49aac894f989182fb9faa487e50a585fbed03 -rdaf4bf00e8ea376485f54faa2fee8497607ddfb0 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2D.cs (.../SoilLayer2D.cs) (revision fcc49aac894f989182fb9faa487e50a585fbed03) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2D.cs (.../SoilLayer2D.cs) (revision daf4bf00e8ea376485f54faa2fee8497607ddfb0) @@ -27,7 +27,6 @@ using Core.Common.Base.Geometry; using Ringtoets.Piping.Data; -using Ringtoets.Piping.Data.Calculation; using Ringtoets.Piping.IO.Properties; namespace Ringtoets.Piping.IO.Builders Fisheye: Tag daf4bf00e8ea376485f54faa2fee8497607ddfb0 refers to a dead (removed) revision in file `Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Calculation/Math2DTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Ringtoets.Piping.Data.Test.csproj =================================================================== diff -u -rfcc49aac894f989182fb9faa487e50a585fbed03 -rdaf4bf00e8ea376485f54faa2fee8497607ddfb0 --- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Ringtoets.Piping.Data.Test.csproj (.../Ringtoets.Piping.Data.Test.csproj) (revision fcc49aac894f989182fb9faa487e50a585fbed03) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Ringtoets.Piping.Data.Test.csproj (.../Ringtoets.Piping.Data.Test.csproj) (revision daf4bf00e8ea376485f54faa2fee8497607ddfb0) @@ -58,7 +58,6 @@ -