Index: Core/Common/src/Core.Common.Base/Core.Common.Base.csproj =================================================================== diff -u -r07b0e83704b56684d617cd6e8b8570417654912a -r27e5d9fb2ffd87ea219ecfb4217a8080f819df62 --- Core/Common/src/Core.Common.Base/Core.Common.Base.csproj (.../Core.Common.Base.csproj) (revision 07b0e83704b56684d617cd6e8b8570417654912a) +++ Core/Common/src/Core.Common.Base/Core.Common.Base.csproj (.../Core.Common.Base.csproj) (revision 27e5d9fb2ffd87ea219ecfb4217a8080f819df62) @@ -93,6 +93,7 @@ + Index: Core/Common/src/Core.Common.Base/Geometry/Point3DExtensions.cs =================================================================== diff -u --- Core/Common/src/Core.Common.Base/Geometry/Point3DExtensions.cs (revision 0) +++ Core/Common/src/Core.Common.Base/Geometry/Point3DExtensions.cs (revision 27e5d9fb2ffd87ea219ecfb4217a8080f819df62) @@ -0,0 +1,84 @@ +// 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 MathNet.Numerics.LinearAlgebra; + +namespace Core.Common.Base.Geometry +{ + /// + /// Extension methods for . + /// + public static class Point3DExtensions + { + /// + /// This method defines the 'spanning line' as the 2D vector going from + /// to . Then the is projected onto + /// this vector. Then the local coordinate is determined by taking the length of each vector along the 'spanning line'. + /// + /// The point to project. + /// The start of the 'spanning line'. + /// The end point of the 'spanning line'. + /// Thrown when either: + /// + /// is null. + /// is null. + /// is null. + /// + /// + /// Thrown when the + /// and the are the same. + public static Point2D ProjectIntoLocalCoordinates(this Point3D worldCoordinate, Point2D startWorldCoordinate, Point2D endWorldCoordinate) + { + if (worldCoordinate == null) + { + throw new ArgumentNullException("worldCoordinate"); + } + if (startWorldCoordinate == null) + { + throw new ArgumentNullException("startWorldCoordinate"); + } + if (endWorldCoordinate == null) + { + throw new ArgumentNullException("endWorldCoordinate"); + } + + Point2D worldCoordinate2D = new Point2D(worldCoordinate.X, worldCoordinate.Y); + Vector vectorToPoint = (worldCoordinate2D - startWorldCoordinate); + + // Determine the 'spanning line' vector: + Vector spanningVector = endWorldCoordinate - startWorldCoordinate; + double spanningVectorDotProduct = spanningVector.DotProduct(spanningVector); + double length = Math.Sqrt(spanningVectorDotProduct); + + if (Math.Abs(length) < 1e-6) + { + throw new ArgumentException("The startWorldCoordinate and endWorldCoordinate can't be the same."); + } + + // Project vector onto the 'spanning vector' to determine it's X coordinate in local coordinates: + double projectOnSpanningVectorFactor = (vectorToPoint.DotProduct(spanningVector)) / spanningVectorDotProduct; + double localCoordinateX = projectOnSpanningVectorFactor * length; + + return new Point2D(localCoordinateX, worldCoordinate.Z); + } + } +} \ No newline at end of file Index: Core/Common/test/Core.Common.Base.Test/Core.Common.Base.Test.csproj =================================================================== diff -u -r07b0e83704b56684d617cd6e8b8570417654912a -r27e5d9fb2ffd87ea219ecfb4217a8080f819df62 --- Core/Common/test/Core.Common.Base.Test/Core.Common.Base.Test.csproj (.../Core.Common.Base.Test.csproj) (revision 07b0e83704b56684d617cd6e8b8570417654912a) +++ Core/Common/test/Core.Common.Base.Test/Core.Common.Base.Test.csproj (.../Core.Common.Base.Test.csproj) (revision 27e5d9fb2ffd87ea219ecfb4217a8080f819df62) @@ -85,6 +85,7 @@ + Index: Core/Common/test/Core.Common.Base.Test/Geometry/Point3DExtensionsTest.cs =================================================================== diff -u --- Core/Common/test/Core.Common.Base.Test/Geometry/Point3DExtensionsTest.cs (revision 0) +++ Core/Common/test/Core.Common.Base.Test/Geometry/Point3DExtensionsTest.cs (revision 27e5d9fb2ffd87ea219ecfb4217a8080f819df62) @@ -0,0 +1,106 @@ +// 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 Core.Common.Base.Geometry; +using Core.Common.TestUtil; +using NUnit.Framework; + +namespace Core.Common.Base.Test.Geometry +{ + [TestFixture] + public class Point3DExtensionsTest + { + [Test] + public void ProjectIntoLocalCoordinates_WorldCoordinateNull_ThrowsArgumentNullException() + { + // Call + TestDelegate call = () => Point3DExtensions.ProjectIntoLocalCoordinates(null, new Point2D(1.0, 2.0), new Point2D(3.0, 4.0)); + + // Assert + var exception = Assert.Throws(call); + Assert.AreEqual("worldCoordinate", exception.ParamName); + } + + [Test] + public void ProjectIntoLocalCoordinates_StartWorldCoordinateNull_ThrowsArgumentNullException() + { + // Setup + Point3D point = new Point3D(1.0, 2.0, 3.0); + + // Call + TestDelegate call = () => point.ProjectIntoLocalCoordinates(null, new Point2D(3.0, 4.0)); + + // Assert + var exception = Assert.Throws(call); + Assert.AreEqual("startWorldCoordinate", exception.ParamName); + } + + [Test] + public void ProjectIntoLocalCoordinates_EndWorldCoordinateNull_ThrowsArgumentNullException() + { + // Setup + Point3D point = new Point3D(1.0, 2.0, 3.0); + + // Call + TestDelegate call = () => point.ProjectIntoLocalCoordinates(new Point2D(1.0, 2.0), null); + + // Assert + var exception = Assert.Throws(call); + Assert.AreEqual("endWorldCoordinate", exception.ParamName); + } + + [Test] + public void ProjectIntoLocalCoordinates_WorldCoordinateSameAsStartAndEndWordlCoordinate_ThrowsArgumentException() + { + // Setup + const double originalZ = 3.3; + Point3D point = new Point3D(1.1, 2.2, originalZ); + + Point2D startAndEndPoint = new Point2D(point.X, point.Y); + + // Call + TestDelegate call = () => point.ProjectIntoLocalCoordinates(startAndEndPoint, startAndEndPoint); + + // Assert + TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, "The startWorldCoordinate and endWorldCoordinate can't be the same."); + } + + [Test] + public void ProjectIntoLocalCoordinates_GeometryWithMultiplePoints_ProjectPointsOntoLzPlaneKeepingOriginalZ() + { + // Setup + Point2D startPoint = new Point2D(1.0, 1.0); + Point3D pointToConvert = new Point3D(2.0, 3.0, 4.4); // Outlier from line specified by extrema + Point2D endPoint = new Point2D(3.0, 4.0); + + // Call + Point2D convertedPoint = pointToConvert.ProjectIntoLocalCoordinates(startPoint, endPoint); + + // Assert + var length = Math.Sqrt(2 * 2 + 3 * 3); + const double pointToConvertCoordinateFactor = (2.0 * 1.0 + 3.0 * 2.0) / (2.0 * 2.0 + 3.0 * 3.0); + double expectedX = pointToConvertCoordinateFactor * length; + + Assert.AreEqual(new Point2D(expectedX, pointToConvert.Z), convertedPoint); + } + } +} \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingChartDataFactory.cs =================================================================== diff -u -r02b8ab97baeb969e7e4008124fe05ffd944e2142 -r27e5d9fb2ffd87ea219ecfb4217a8080f819df62 --- Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingChartDataFactory.cs (.../PipingChartDataFactory.cs) (revision 02b8ab97baeb969e7e4008124fe05ffd944e2142) +++ Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingChartDataFactory.cs (.../PipingChartDataFactory.cs) (revision 27e5d9fb2ffd87ea219ecfb4217a8080f819df62) @@ -112,14 +112,14 @@ /// The for which to create . /// based on the . /// /// Thrown when is null. - public static ChartData CreateDitchPolderSide(Point3D ditchPolderSide) + public static ChartData CreateDitchPolderSide(RingtoetsPipingSurfaceLine surfaceLine) { - if (ditchPolderSide == null) + if (surfaceLine == null) { - throw new ArgumentNullException("ditchPolderSide"); + throw new ArgumentNullException("surfaceLine"); } - return CreatePoint(ditchPolderSide, PipingDataResources.CharacteristicPoint_DitchPolderSide, new ChartPointStyle(Color.Red, 8, Color.Transparent, 0, ChartPointSymbol.Circle)); + return CreateLocalPoint(surfaceLine.DitchPolderSide, surfaceLine, PipingDataResources.CharacteristicPoint_DitchPolderSide, new ChartPointStyle(Color.Red, 8, Color.Transparent, 0, ChartPointSymbol.Circle)); } /// @@ -128,14 +128,14 @@ /// The for which to create . /// based on the . /// /// Thrown when is null. - public static ChartData CreateBottomDitchPolderSide(Point3D bottomDitchPolderSide) + public static ChartData CreateBottomDitchPolderSide(RingtoetsPipingSurfaceLine surfaceLine) { - if (bottomDitchPolderSide == null) + if (surfaceLine == null) { - throw new ArgumentNullException("bottomDitchPolderSide"); + throw new ArgumentNullException("surfaceLine"); } - return CreatePoint(bottomDitchPolderSide, PipingDataResources.CharacteristicPoint_BottomDitchPolderSide, new ChartPointStyle(Color.Blue, 8, Color.Transparent, 0, ChartPointSymbol.Circle)); + return CreateLocalPoint(surfaceLine.BottomDitchPolderSide, surfaceLine, PipingDataResources.CharacteristicPoint_BottomDitchPolderSide, new ChartPointStyle(Color.Blue, 8, Color.Transparent, 0, ChartPointSymbol.Circle)); } /// @@ -144,14 +144,14 @@ /// The for which to create . /// based on the . /// /// Thrown when is null. - public static ChartData CreateBottomDitchDikeSide(Point3D bottomDitchDikeSide) + public static ChartData CreateBottomDitchDikeSide(RingtoetsPipingSurfaceLine surfaceLine) { - if (bottomDitchDikeSide == null) + if (surfaceLine == null) { - throw new ArgumentNullException("bottomDitchDikeSide"); + throw new ArgumentNullException("surfaceLine"); } - return CreatePoint(bottomDitchDikeSide, PipingDataResources.CharacteristicPoint_BottomDitchDikeSide, new ChartPointStyle(Color.Green, 8, Color.Transparent, 0, ChartPointSymbol.Circle)); + return CreateLocalPoint(surfaceLine.BottomDitchDikeSide, surfaceLine, PipingDataResources.CharacteristicPoint_BottomDitchDikeSide, new ChartPointStyle(Color.Green, 8, Color.Transparent, 0, ChartPointSymbol.Circle)); } /// @@ -160,14 +160,14 @@ /// The for which to create . /// based on the . /// /// Thrown when is null. - public static ChartData CreateDitchDikeSide(Point3D ditchDikeSide) + public static ChartData CreateDitchDikeSide(RingtoetsPipingSurfaceLine surfaceLine) { - if (ditchDikeSide == null) + if (surfaceLine == null) { - throw new ArgumentNullException("ditchDikeSide"); + throw new ArgumentNullException("surfaceLine"); } - return CreatePoint(ditchDikeSide, PipingDataResources.CharacteristicPoint_DitchDikeSide, new ChartPointStyle(Color.Purple, 8, Color.Transparent, 0, ChartPointSymbol.Circle)); + return CreateLocalPoint(surfaceLine.DitchDikeSide, surfaceLine, PipingDataResources.CharacteristicPoint_DitchDikeSide, new ChartPointStyle(Color.Purple, 8, Color.Transparent, 0, ChartPointSymbol.Circle)); } /// @@ -176,14 +176,14 @@ /// The for which to create . /// based on the . /// /// Thrown when is null. - public static ChartData CreateDikeToeAtRiver(Point3D dikeToeAtRiver) + public static ChartData CreateDikeToeAtRiver(RingtoetsPipingSurfaceLine surfaceLine) { - if (dikeToeAtRiver == null) + if (surfaceLine == null) { - throw new ArgumentNullException("dikeToeAtRiver"); + throw new ArgumentNullException("surfaceLine"); } - return CreatePoint(dikeToeAtRiver, PipingDataResources.CharacteristicPoint_DikeToeAtRiver, new ChartPointStyle(Color.Orange, 8, Color.Transparent, 0, ChartPointSymbol.Circle)); + return CreateLocalPoint(surfaceLine.DikeToeAtRiver, surfaceLine, PipingDataResources.CharacteristicPoint_DikeToeAtRiver, new ChartPointStyle(Color.Orange, 8, Color.Transparent, 0, ChartPointSymbol.Circle)); } /// @@ -192,21 +192,23 @@ /// The for which to create . /// based on the . /// /// Thrown when is null. - public static ChartData CreateDikeToeAtPolder(Point3D dikeToeAtPolder) + public static ChartData CreateDikeToeAtPolder(RingtoetsPipingSurfaceLine surfaceLine) { - if (dikeToeAtPolder == null) + if (surfaceLine == null) { - throw new ArgumentNullException("dikeToeAtPolder"); + throw new ArgumentNullException("surfaceLine"); } - return CreatePoint(dikeToeAtPolder, PipingDataResources.CharacteristicPoint_DikeToeAtPolder, new ChartPointStyle(Color.Silver, 8, Color.Transparent, 0, ChartPointSymbol.Circle)); + return CreateLocalPoint(surfaceLine.DikeToeAtPolder, surfaceLine, PipingDataResources.CharacteristicPoint_DikeToeAtPolder, new ChartPointStyle(Color.Silver, 8, Color.Transparent, 0, ChartPointSymbol.Circle)); } - private static ChartData CreatePoint(Point3D dikeToeAtRiver, string name, ChartPointStyle style) + private static ChartData CreateLocalPoint(Point3D worldPoint, RingtoetsPipingSurfaceLine surfaceLine, string name, ChartPointStyle style) { + Point2D firstPoint = Point3DToPoint2D(surfaceLine.Points.First()); + Point2D lastPoint = Point3DToPoint2D(surfaceLine.Points.Last()); return new ChartPointData(new[] { - Point3DToPoint2D(dikeToeAtRiver) + worldPoint.ProjectIntoLocalCoordinates(firstPoint, lastPoint) }, name) { Style = style @@ -215,7 +217,7 @@ private static Point2D Point3DToPoint2D(Point3D point3D) { - return new Point2D(point3D.X, point3D.Z); + return new Point2D(point3D.X, point3D.Y); } } } \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingInputView.cs =================================================================== diff -u -r02b8ab97baeb969e7e4008124fe05ffd944e2142 -r27e5d9fb2ffd87ea219ecfb4217a8080f819df62 --- Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingInputView.cs (.../PipingInputView.cs) (revision 02b8ab97baeb969e7e4008124fe05ffd944e2142) +++ Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingInputView.cs (.../PipingInputView.cs) (revision 27e5d9fb2ffd87ea219ecfb4217a8080f819df62) @@ -120,14 +120,14 @@ if (data != null) { // Bottom most layer + surfaceLineData = AddOrUpdateChartData(surfaceLineData, GetSurfaceLineChartData()); ditchPolderSideData = AddOrUpdateChartData(ditchPolderSideData, GetDitchPolderSideData()); bottomDitchPolderSidePointData = AddOrUpdateChartData(bottomDitchPolderSidePointData, GetBottomDitchPolderSideData()); bottomDitchDikeSidePointData = AddOrUpdateChartData(bottomDitchDikeSidePointData, GetBottomDitchDikeSideData()); ditchDikeSidePointData = AddOrUpdateChartData(ditchDikeSidePointData, GetDitchDikeSideData()); dikeToeAtRiverPointData = AddOrUpdateChartData(dikeToeAtRiverPointData, GetDikeToeAtRiverData()); dikeToeAtPolderPointData = AddOrUpdateChartData(dikeToeAtPolderPointData, GetDikeToeAtPolderData()); entryPointData = AddOrUpdateChartData(entryPointData, GetEntryPointChartData()); - surfaceLineData = AddOrUpdateChartData(surfaceLineData, GetSurfaceLineChartData()); // Top most layer } @@ -158,7 +158,7 @@ { return PipingChartDataFactory.CreateEmptyPointData(PipingDataResources.CharacteristicPoint_DitchPolderSide); } - return PipingChartDataFactory.CreateDitchPolderSide(data.SurfaceLine.DitchPolderSide); + return PipingChartDataFactory.CreateDitchPolderSide(data.SurfaceLine); } private ChartData GetBottomDitchPolderSideData() @@ -167,7 +167,7 @@ { return PipingChartDataFactory.CreateEmptyPointData(PipingDataResources.CharacteristicPoint_BottomDitchPolderSide); } - return PipingChartDataFactory.CreateBottomDitchPolderSide(data.SurfaceLine.BottomDitchPolderSide); + return PipingChartDataFactory.CreateBottomDitchPolderSide(data.SurfaceLine); } private ChartData GetBottomDitchDikeSideData() @@ -176,7 +176,7 @@ { return PipingChartDataFactory.CreateEmptyPointData(PipingDataResources.CharacteristicPoint_BottomDitchDikeSide); } - return PipingChartDataFactory.CreateBottomDitchDikeSide(data.SurfaceLine.BottomDitchDikeSide); + return PipingChartDataFactory.CreateBottomDitchDikeSide(data.SurfaceLine); } private ChartData GetDitchDikeSideData() @@ -185,7 +185,7 @@ { return PipingChartDataFactory.CreateEmptyPointData(PipingDataResources.CharacteristicPoint_DitchDikeSide); } - return PipingChartDataFactory.CreateDitchDikeSide(data.SurfaceLine.DitchDikeSide); + return PipingChartDataFactory.CreateDitchDikeSide(data.SurfaceLine); } private ChartData GetDikeToeAtRiverData() @@ -194,7 +194,7 @@ { return PipingChartDataFactory.CreateEmptyPointData(PipingDataResources.CharacteristicPoint_DikeToeAtRiver); } - return PipingChartDataFactory.CreateDikeToeAtRiver(data.SurfaceLine.DikeToeAtRiver); + return PipingChartDataFactory.CreateDikeToeAtRiver(data.SurfaceLine); } private ChartData GetDikeToeAtPolderData() @@ -203,7 +203,7 @@ { return PipingChartDataFactory.CreateEmptyPointData(PipingDataResources.CharacteristicPoint_DikeToeAtPolder); } - return PipingChartDataFactory.CreateDikeToeAtPolder(data.SurfaceLine.DikeToeAtPolder); + return PipingChartDataFactory.CreateDikeToeAtPolder(data.SurfaceLine); } private ChartData AddOrUpdateChartData(ChartData oldChartData, ChartData newChartData) Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/SurfaceLines/PipingSurfaceLinesCsvReader.cs =================================================================== diff -u -rbbf8e2a3fb6e709c7d7a5ddbd955575f83720cc0 -r27e5d9fb2ffd87ea219ecfb4217a8080f819df62 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/SurfaceLines/PipingSurfaceLinesCsvReader.cs (.../PipingSurfaceLinesCsvReader.cs) (revision bbf8e2a3fb6e709c7d7a5ddbd955575f83720cc0) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/SurfaceLines/PipingSurfaceLinesCsvReader.cs (.../PipingSurfaceLinesCsvReader.cs) (revision 27e5d9fb2ffd87ea219ecfb4217a8080f819df62) @@ -213,8 +213,8 @@ /// Surface line geometry is invalid. private void CheckIfGeometryIsValid(RingtoetsPipingSurfaceLine surfaceLine) { - CheckReclinging(surfaceLine); CheckZeroLength(surfaceLine); + CheckReclinging(surfaceLine); } private void CheckZeroLength(RingtoetsPipingSurfaceLine surfaceLine) Index: Ringtoets/Piping/src/Ringtoets.Piping.Primitives/RingtoetsPipingSurfaceLine.cs =================================================================== diff -u -r93ca6aa3bd94ccb82da7d62f13cc9fa009f1443c -r27e5d9fb2ffd87ea219ecfb4217a8080f819df62 --- Ringtoets/Piping/src/Ringtoets.Piping.Primitives/RingtoetsPipingSurfaceLine.cs (.../RingtoetsPipingSurfaceLine.cs) (revision 93ca6aa3bd94ccb82da7d62f13cc9fa009f1443c) +++ Ringtoets/Piping/src/Ringtoets.Piping.Primitives/RingtoetsPipingSurfaceLine.cs (.../RingtoetsPipingSurfaceLine.cs) (revision 27e5d9fb2ffd87ea219ecfb4217a8080f819df62) @@ -289,21 +289,16 @@ return Enumerable.Empty(); } - var localCoordinatesX = new double[count]; - localCoordinatesX[0] = 0.0; - if (count > 1) + Point3D first = Points.First(); + if (count == 1) { - ProjectPointsAfterFirstOntoSpanningLine(localCoordinatesX); + return new[] { new Point2D(0.0, first.Z)}; } - var result = new Point2D[count]; - for (int i = 0; i < count; i++) - { - var x = localCoordinatesX[i]; - var y = geometryPoints[i].Z; - result[i] = new Point2D(x, y); - } - return result; + Point3D last = Points.Last(); + Point2D firstPoint = new Point2D(first.X, first.Y); + Point2D lastPoint = new Point2D(last.X, last.Y); + return Points.Select(p => p.ProjectIntoLocalCoordinates(firstPoint, lastPoint)); } public override string ToString() @@ -367,40 +362,5 @@ throw new ArgumentOutOfRangeException("localCoordinateL", outOfRangeMessage); } } - - /// - /// This method defines the 'spanning line' as the 2D vector going from start to end - /// of the surface line points. Then all except the first point is projected onto - /// this vector. Then the local coordinates are determined by taking the length of - /// each vector along the 'spanning line'. - /// - /// The array into which the projected X-coordinate - /// values should be stored. Its should be the same as - /// the collection-size of . - private void ProjectPointsAfterFirstOntoSpanningLine(double[] localCoordinatesX) - { - // 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]; - 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]; - double spanningVectorDotProduct = spanningVector.DotProduct(spanningVector); - double length = Math.Sqrt(spanningVectorDotProduct); - - // Project each vector onto the 'spanning vector' to determine it's X coordinate in local coordinates: - for (int i = 0; i < worldCoordinateVectors.Length - 1; i++) - { - double projectOnSpanningVectorFactor = (worldCoordinateVectors[i].DotProduct(spanningVector)) / - (spanningVectorDotProduct); - localCoordinatesX[i + 1] = projectOnSpanningVectorFactor * length; - } - localCoordinatesX[localCoordinatesX.Length - 1] = length; - } } } \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/Views/PipingChartDataFactoryTest.cs =================================================================== diff -u -r2206475a63c65a3af17ad81352699de1ca2cadcf -r27e5d9fb2ffd87ea219ecfb4217a8080f819df62 --- Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/Views/PipingChartDataFactoryTest.cs (.../PipingChartDataFactoryTest.cs) (revision 2206475a63c65a3af17ad81352699de1ca2cadcf) +++ Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/Views/PipingChartDataFactoryTest.cs (.../PipingChartDataFactoryTest.cs) (revision 27e5d9fb2ffd87ea219ecfb4217a8080f819df62) @@ -176,25 +176,34 @@ // Assert var exception = Assert.Throws(call); - Assert.AreEqual("ditchPolderSide", exception.ParamName); + Assert.AreEqual("surfaceLine", exception.ParamName); } [Test] public void CreateDitchPolderSide_GivenDitchPolderSide_ReturnsChartDataWithDefaultStyling() { // Setup - Point3D ditchPolderSide = new Point3D(1.0, 4.3, 6.4); + Point3D ditchPolderSide = new Point3D(1.2, 2.3, 4.0); + var points = new[] + { + new Point3D(1.2, 2.3, 4.0), + new Point3D(2.7, 2.0, 6.0) + }; + var surfaceLine = new RingtoetsPipingSurfaceLine(); + surfaceLine.SetGeometry(points); + surfaceLine.SetDitchPolderSideAt(ditchPolderSide); + // Call - ChartData data = PipingChartDataFactory.CreateDitchPolderSide(ditchPolderSide); + ChartData data = PipingChartDataFactory.CreateDitchPolderSide(surfaceLine); // Assert Assert.IsInstanceOf(data); ChartPointData chartPointData = (ChartPointData)data; Assert.AreEqual(1, chartPointData.Points.Count()); Assert.AreEqual(PipingDataResources.CharacteristicPoint_DitchPolderSide, chartPointData.Name); - AssertEqualPointCollections(new[] { new Point2D(ditchPolderSide.X, ditchPolderSide.Z) }, chartPointData.Points); + AssertEqualLocalPointCollection(ditchPolderSide, surfaceLine, chartPointData.Points); AssertEqualStyle(chartPointData.Style, Color.Red, 8, Color.Transparent, 0, ChartPointSymbol.Circle); } @@ -203,29 +212,38 @@ public void CreateBottomDitchPolderSide_BottomDitchPolderSideNull_ThrowsArgumentNullException() { // Call - TestDelegate call = () => PipingChartDataFactory.CreateDitchPolderSide(null); + TestDelegate call = () => PipingChartDataFactory.CreateBottomDitchPolderSide(null); // Assert var exception = Assert.Throws(call); - Assert.AreEqual("ditchPolderSide", exception.ParamName); + Assert.AreEqual("surfaceLine", exception.ParamName); } [Test] public void CreateBottomDitchPolderSide_GivenBottomDitchPolderSide_ReturnsChartDataWithDefaultStyling() { // Setup - Point3D bottomDitchPolderSide = new Point3D(1.0, 4.3, 6.4); + Point3D bottomDitchPolderSide = new Point3D(1.2, 2.3, 4.0); + var points = new[] + { + new Point3D(1.2, 2.3, 4.0), + new Point3D(2.7, 2.0, 6.0) + }; + var surfaceLine = new RingtoetsPipingSurfaceLine(); + surfaceLine.SetGeometry(points); + surfaceLine.SetBottomDitchPolderSideAt(bottomDitchPolderSide); + // Call - ChartData data = PipingChartDataFactory.CreateBottomDitchPolderSide(bottomDitchPolderSide); + ChartData data = PipingChartDataFactory.CreateBottomDitchPolderSide(surfaceLine); // Assert Assert.IsInstanceOf(data); ChartPointData chartPointData = (ChartPointData)data; Assert.AreEqual(1, chartPointData.Points.Count()); Assert.AreEqual(PipingDataResources.CharacteristicPoint_BottomDitchPolderSide, chartPointData.Name); - AssertEqualPointCollections(new[] { new Point2D(bottomDitchPolderSide.X, bottomDitchPolderSide.Z) }, chartPointData.Points); + AssertEqualLocalPointCollection(bottomDitchPolderSide, surfaceLine, chartPointData.Points); AssertEqualStyle(chartPointData.Style, Color.Blue, 8, Color.Transparent, 0, ChartPointSymbol.Circle); } @@ -238,25 +256,34 @@ // Assert var exception = Assert.Throws(call); - Assert.AreEqual("bottomDitchDikeSide", exception.ParamName); + Assert.AreEqual("surfaceLine", exception.ParamName); } [Test] public void CreateBottomDitchDikeSide_GivenBottomDitchDikeSide_ReturnsChartDataWithDefaultStyling() { // Setup Point3D bottomDitchDikeSide = new Point3D(1.0, 4.3, 6.4); + var points = new[] + { + new Point3D(1.0, 4.3, 6.4), + new Point3D(2.7, 2.0, 6.0) + }; + var surfaceLine = new RingtoetsPipingSurfaceLine(); + surfaceLine.SetGeometry(points); + surfaceLine.SetBottomDitchDikeSideAt(bottomDitchDikeSide); + // Call - ChartData data = PipingChartDataFactory.CreateBottomDitchDikeSide(bottomDitchDikeSide); + ChartData data = PipingChartDataFactory.CreateBottomDitchDikeSide(surfaceLine); // Assert Assert.IsInstanceOf(data); ChartPointData chartPointData = (ChartPointData)data; Assert.AreEqual(1, chartPointData.Points.Count()); Assert.AreEqual(PipingDataResources.CharacteristicPoint_BottomDitchDikeSide, chartPointData.Name); - AssertEqualPointCollections(new[] { new Point2D(bottomDitchDikeSide.X, bottomDitchDikeSide.Z) }, chartPointData.Points); + AssertEqualLocalPointCollection(bottomDitchDikeSide, surfaceLine, chartPointData.Points); AssertEqualStyle(chartPointData.Style, Color.Green, 8, Color.Transparent, 0, ChartPointSymbol.Circle); } @@ -269,25 +296,34 @@ // Assert var exception = Assert.Throws(call); - Assert.AreEqual("ditchDikeSide", exception.ParamName); + Assert.AreEqual("surfaceLine", exception.ParamName); } [Test] public void CreateDitchDikeSide_GivenDitchDikeSide_ReturnsChartDataWithDefaultStyling() { // Setup Point3D ditchDikeSide = new Point3D(1.0, 4.3, 6.4); + var points = new[] + { + new Point3D(1.0, 4.3, 6.4), + new Point3D(2.7, 2.0, 6.0) + }; + var surfaceLine = new RingtoetsPipingSurfaceLine(); + surfaceLine.SetGeometry(points); + surfaceLine.SetDitchDikeSideAt(ditchDikeSide); + // Call - ChartData data = PipingChartDataFactory.CreateDitchDikeSide(ditchDikeSide); + ChartData data = PipingChartDataFactory.CreateDitchDikeSide(surfaceLine); // Assert Assert.IsInstanceOf(data); ChartPointData chartPointData = (ChartPointData)data; Assert.AreEqual(1, chartPointData.Points.Count()); Assert.AreEqual(PipingDataResources.CharacteristicPoint_DitchDikeSide, chartPointData.Name); - AssertEqualPointCollections(new[] { new Point2D(ditchDikeSide.X, ditchDikeSide.Z) }, chartPointData.Points); + AssertEqualLocalPointCollection(ditchDikeSide, surfaceLine, chartPointData.Points); AssertEqualStyle(chartPointData.Style, Color.Purple, 8, Color.Transparent, 0, ChartPointSymbol.Circle); } @@ -300,25 +336,34 @@ // Assert var exception = Assert.Throws(call); - Assert.AreEqual("dikeToeAtRiver", exception.ParamName); + Assert.AreEqual("surfaceLine", exception.ParamName); } [Test] public void CreateDikeToeAtRiver_GivenDikeToeAtRivere_ReturnsChartDataWithDefaultStyling() { // Setup - Point3D dikeToeAtRiver = new Point3D(1.0, 4.3, 6.4); + Point3D dikeToeAtRiver = new Point3D(1.2, 2.3, 4.0); + var points = new[] + { + new Point3D(1.2, 2.3, 4.0), + new Point3D(2.7, 2.0, 6.0) + }; + var surfaceLine = new RingtoetsPipingSurfaceLine(); + surfaceLine.SetGeometry(points); + surfaceLine.SetDikeToeAtRiverAt(dikeToeAtRiver); + // Call - ChartData data = PipingChartDataFactory.CreateDikeToeAtRiver(dikeToeAtRiver); + ChartData data = PipingChartDataFactory.CreateDikeToeAtRiver(surfaceLine); // Assert Assert.IsInstanceOf(data); ChartPointData chartPointData = (ChartPointData)data; Assert.AreEqual(1, chartPointData.Points.Count()); Assert.AreEqual(PipingDataResources.CharacteristicPoint_DikeToeAtRiver, chartPointData.Name); - AssertEqualPointCollections(new[] { new Point2D(dikeToeAtRiver.X, dikeToeAtRiver.Z) }, chartPointData.Points); + AssertEqualLocalPointCollection(dikeToeAtRiver, surfaceLine, chartPointData.Points); AssertEqualStyle(chartPointData.Style, Color.Orange, 8, Color.Transparent, 0, ChartPointSymbol.Circle); } @@ -331,25 +376,34 @@ // Assert var exception = Assert.Throws(call); - Assert.AreEqual("dikeToeAtPolder", exception.ParamName); + Assert.AreEqual("surfaceLine", exception.ParamName); } [Test] public void CreateDikeToeAtPolder_GivenDikeToeAtPolder_ReturnsChartDataWithDefaultStyling() { // Setup Point3D dikeToeAtPolder = new Point3D(1.0, 4.3, 6.4); + var points = new[] + { + new Point3D(1.0, 4.3, 6.4), + new Point3D(2.7, 2.0, 6.0) + }; + var surfaceLine = new RingtoetsPipingSurfaceLine(); + surfaceLine.SetGeometry(points); + surfaceLine.SetDikeToeAtPolderAt(dikeToeAtPolder); + // Call - ChartData data = PipingChartDataFactory.CreateDikeToeAtPolder(dikeToeAtPolder); + ChartData data = PipingChartDataFactory.CreateDikeToeAtPolder(surfaceLine); // Assert Assert.IsInstanceOf(data); ChartPointData chartPointData = (ChartPointData)data; Assert.AreEqual(1, chartPointData.Points.Count()); Assert.AreEqual(PipingDataResources.CharacteristicPoint_DikeToeAtPolder, chartPointData.Name); - AssertEqualPointCollections(new[] { new Point2D(dikeToeAtPolder.X, dikeToeAtPolder.Z) }, chartPointData.Points); + AssertEqualLocalPointCollection(dikeToeAtPolder, surfaceLine, chartPointData.Points); AssertEqualStyle(chartPointData.Style, Color.Silver, 8, Color.Transparent, 0, ChartPointSymbol.Circle); } @@ -359,6 +413,16 @@ CollectionAssert.AreEqual(points.Select(p => new Point2D(p.X, p.Y)), chartPoints); } + private void AssertEqualLocalPointCollection(Point3D point, RingtoetsPipingSurfaceLine surfaceLine, IEnumerable chartPoints) + { + Point3D first = surfaceLine.Points.First(); + Point3D last = surfaceLine.Points.Last(); + Point2D firstPoint = new Point2D(first.X, first.Y); + Point2D lastPoint = new Point2D(last.X, last.Y); + + AssertEqualPointCollections(new[] { point.ProjectIntoLocalCoordinates(firstPoint, lastPoint) }, chartPoints); + } + private void AssertEqualStyle(ChartLineStyle lineStyle, Color color, int width, DashStyle style) { Assert.AreEqual(color, lineStyle.Color); Index: Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/Views/PipingInputViewTest.cs =================================================================== diff -u -r02b8ab97baeb969e7e4008124fe05ffd944e2142 -r27e5d9fb2ffd87ea219ecfb4217a8080f819df62 --- Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/Views/PipingInputViewTest.cs (.../PipingInputViewTest.cs) (revision 02b8ab97baeb969e7e4008124fe05ffd944e2142) +++ Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/Views/PipingInputViewTest.cs (.../PipingInputViewTest.cs) (revision 27e5d9fb2ffd87ea219ecfb4217a8080f819df62) @@ -568,14 +568,14 @@ } } - private const int ditchPolderSideIndex = 0; - private const int bottomDitchPolderSideIndex = 1; - private const int bottomDitchDikeSideIndex = 2; - private const int ditchDikeSideIndex = 3; - private const int dikeToeAtRiverIndex = 4; - private const int dikeToeAtPolderIndex = 5; - private const int entryPointIndex = 6; - private const int surfaceLineIndex = 7; + private const int surfaceLineIndex = 0; + private const int ditchPolderSideIndex = 1; + private const int bottomDitchPolderSideIndex = 2; + private const int bottomDitchDikeSideIndex = 3; + private const int ditchDikeSideIndex = 4; + private const int dikeToeAtRiverIndex = 5; + private const int dikeToeAtPolderIndex = 6; + private const int entryPointIndex = 7; private void AssertSurfaceLineChartData(RingtoetsPipingSurfaceLine surfaceLine, ChartData chartData) { @@ -600,40 +600,40 @@ private void AssertCharacteristicPoints(RingtoetsPipingSurfaceLine surfaceLine, IList characteristicPoints) { + Point3D first = surfaceLine.Points.First(); + Point3D last = surfaceLine.Points.Last(); + Point2D firstPoint = new Point2D(first.X, first.Y); + Point2D lastPoint = new Point2D(last.X, last.Y); + var ditchDikeSideData = (ChartPointData)characteristicPoints[ditchDikeSideIndex]; Assert.AreEqual(1, ditchDikeSideData.Points.Count()); - CollectionAssert.AreEqual(new[] { Get2DPoint(surfaceLine.DitchDikeSide) }, ditchDikeSideData.Points); + CollectionAssert.AreEqual(new[] { surfaceLine.DitchDikeSide.ProjectIntoLocalCoordinates(firstPoint, lastPoint) }, ditchDikeSideData.Points); Assert.AreEqual(PipingDataResources.CharacteristicPoint_DitchDikeSide, ditchDikeSideData.Name); var bottomDitchDikeSideData = (ChartPointData)characteristicPoints[bottomDitchDikeSideIndex]; Assert.AreEqual(1, bottomDitchDikeSideData.Points.Count()); - CollectionAssert.AreEqual(new[] { Get2DPoint(surfaceLine.BottomDitchDikeSide) }, bottomDitchDikeSideData.Points); + CollectionAssert.AreEqual(new[] { surfaceLine.BottomDitchDikeSide.ProjectIntoLocalCoordinates(firstPoint, lastPoint) }, bottomDitchDikeSideData.Points); Assert.AreEqual(PipingDataResources.CharacteristicPoint_BottomDitchDikeSide, bottomDitchDikeSideData.Name); var ditchPolderSideData = (ChartPointData)characteristicPoints[ditchPolderSideIndex]; Assert.AreEqual(1, ditchPolderSideData.Points.Count()); - CollectionAssert.AreEqual(new[] { Get2DPoint(surfaceLine.DitchPolderSide) }, ditchPolderSideData.Points); + CollectionAssert.AreEqual(new[] { surfaceLine.DitchPolderSide.ProjectIntoLocalCoordinates(firstPoint, lastPoint) }, ditchPolderSideData.Points); Assert.AreEqual(PipingDataResources.CharacteristicPoint_DitchPolderSide, ditchPolderSideData.Name); var bottomDitchPolderSideData = (ChartPointData)characteristicPoints[bottomDitchPolderSideIndex]; Assert.AreEqual(1, bottomDitchPolderSideData.Points.Count()); - CollectionAssert.AreEqual(new[] { Get2DPoint(surfaceLine.BottomDitchPolderSide) }, bottomDitchPolderSideData.Points); + CollectionAssert.AreEqual(new[] { surfaceLine.BottomDitchPolderSide.ProjectIntoLocalCoordinates(firstPoint, lastPoint) }, bottomDitchPolderSideData.Points); Assert.AreEqual(PipingDataResources.CharacteristicPoint_BottomDitchPolderSide, bottomDitchPolderSideData.Name); var dikeToeAtPolderData = (ChartPointData)characteristicPoints[dikeToeAtPolderIndex]; Assert.AreEqual(1, dikeToeAtPolderData.Points.Count()); - CollectionAssert.AreEqual(new[] { Get2DPoint(surfaceLine.DikeToeAtPolder) }, dikeToeAtPolderData.Points); + CollectionAssert.AreEqual(new[] { surfaceLine.DikeToeAtPolder.ProjectIntoLocalCoordinates(firstPoint, lastPoint) }, dikeToeAtPolderData.Points); Assert.AreEqual(PipingDataResources.CharacteristicPoint_DikeToeAtPolder, dikeToeAtPolderData.Name); var dikeToeAtRiverData = (ChartPointData)characteristicPoints[dikeToeAtRiverIndex]; Assert.AreEqual(1, dikeToeAtRiverData.Points.Count()); - CollectionAssert.AreEqual(new[] { Get2DPoint(surfaceLine.DikeToeAtRiver) }, dikeToeAtRiverData.Points); + CollectionAssert.AreEqual(new[] { surfaceLine.DikeToeAtRiver.ProjectIntoLocalCoordinates(firstPoint, lastPoint) }, dikeToeAtRiverData.Points); Assert.AreEqual(PipingDataResources.CharacteristicPoint_DikeToeAtRiver, dikeToeAtRiverData.Name); } - - private Point2D Get2DPoint(Point3D point3D) - { - return new Point2D(point3D.X, point3D.Z); - } } } \ No newline at end of file