Index: Ringtoets/Piping/src/Ringtoets.Piping.Primitives/RingtoetsPipingSurfaceLine.cs =================================================================== diff -u -r35db69dfe64b7e7deeaf9ef85d4df42ff6009b11 -r619da07034480d4ba9e59fe0bea2dd06d83963e0 --- Ringtoets/Piping/src/Ringtoets.Piping.Primitives/RingtoetsPipingSurfaceLine.cs (.../RingtoetsPipingSurfaceLine.cs) (revision 35db69dfe64b7e7deeaf9ef85d4df42ff6009b11) +++ Ringtoets/Piping/src/Ringtoets.Piping.Primitives/RingtoetsPipingSurfaceLine.cs (.../RingtoetsPipingSurfaceLine.cs) (revision 619da07034480d4ba9e59fe0bea2dd06d83963e0) @@ -37,15 +37,15 @@ public class RingtoetsPipingSurfaceLine : IStorable { private const int numberOfDecimalPlaces = 2; - private Point3D[] geometryPoints; + private Point2D[] localGeometry; /// /// Initializes a new instance of the class. /// public RingtoetsPipingSurfaceLine() { Name = string.Empty; - geometryPoints = new Point3D[0]; + Points = new Point3D[0]; } /// @@ -56,13 +56,7 @@ /// /// Gets the 3D points describing its geometry. /// - public Point3D[] Points - { - get - { - return geometryPoints; - } - } + public Point3D[] Points { get; private set; } /// /// Gets or sets the first 3D geometry point defining the surfaceline in world coordinates. @@ -109,6 +103,17 @@ /// public Point2D ReferenceLineIntersectionWorldPoint { get; set; } + /// + /// Gets the 2D points describing the local geometry of the surface line. + /// + public Point2D[] LocalGeometry + { + get + { + return localGeometry ?? (localGeometry = ProjectGeometryToLZ().ToArray()); + } + } + public long StorageId { get; set; } /// @@ -127,13 +132,15 @@ { throw new ArgumentException(Resources.RingtoetsPipingSurfaceLine_A_point_in_the_collection_was_null); } - geometryPoints = points.ToArray(); + Points = points.ToArray(); - if (geometryPoints.Length > 0) + if (Points.Length > 0) { - StartingWorldPoint = geometryPoints[0]; - EndingWorldPoint = geometryPoints[geometryPoints.Length - 1]; + StartingWorldPoint = Points[0]; + EndingWorldPoint = Points[Points.Length - 1]; } + + localGeometry = null; } /// @@ -251,19 +258,24 @@ { ValidateHasPoints(); - Point2D[] pointsInLocalCoordinates = ProjectGeometryToLZ().ToArray(); + if (!ValidateInRange(l)) + { + var outOfRangeMessage = string.Format(Resources.RingtoetsPipingSurfaceLine_0_L_needs_to_be_in_1_2_range, + Resources.RingtoetsPipingSurfaceLine_GetZAtL_Cannot_determine_height, + LocalGeometry.First().X, + LocalGeometry.Last().X); + throw new ArgumentOutOfRangeException(null, outOfRangeMessage); + } - ValidateInRange(l, pointsInLocalCoordinates); - var segments = new Collection(); - for (int i = 1; i < pointsInLocalCoordinates.Length; i++) + for (int i = 1; i < localGeometry.Length; i++) { - segments.Add(new Segment2D(pointsInLocalCoordinates[i - 1], pointsInLocalCoordinates[i])); + segments.Add(new Segment2D(LocalGeometry[i - 1], LocalGeometry[i])); } IEnumerable intersectionPoints = Math2D.SegmentsIntersectionWithVerticalLine(segments, l).OrderBy(p => p.Y).ToArray(); - const double intersectionTolerance = 1e-6; + const double intersectionTolerance = 1e-2; bool equalIntersections = Math.Abs(intersectionPoints.First().Y - intersectionPoints.Last().Y) < intersectionTolerance; if (equalIntersections) @@ -282,7 +294,7 @@ /// Collection of 2D points in the LZ-plane. public RoundedPoint2DCollection ProjectGeometryToLZ() { - var count = geometryPoints.Length; + var count = Points.Length; if (count == 0) { return new RoundedPoint2DCollection(numberOfDecimalPlaces, Enumerable.Empty()); @@ -291,7 +303,10 @@ Point3D first = Points.First(); if (count == 1) { - return new RoundedPoint2DCollection(numberOfDecimalPlaces, new[] { new Point2D(0.0, first.Z)}); + return new RoundedPoint2DCollection(numberOfDecimalPlaces, new[] + { + new Point2D(0.0, first.Z) + }); } Point3D last = Points.Last(); @@ -300,6 +315,20 @@ return new RoundedPoint2DCollection(numberOfDecimalPlaces, Points.Select(p => p.ProjectIntoLocalCoordinates(firstPoint, lastPoint))); } + /// + /// Checks whether is in range of the geometry projected in local coordinate system + /// where the points are ordered on the L-coordinate being monotonically non-decreasing. + /// + /// The local L-coordinate value to check for. + /// true when local L-coordinate is in range of the local geometry. false otherwise. + public bool ValidateInRange(double localCoordinateL) + { + Point2D firstLocalPoint = LocalGeometry.First(); + Point2D lastLocalPoint = LocalGeometry.Last(); + RoundedDouble roundedLocalCoordinateL = new RoundedDouble(numberOfDecimalPlaces, localCoordinateL); + return !(firstLocalPoint.X > roundedLocalCoordinateL) && !(lastLocalPoint.X < roundedLocalCoordinateL); + } + public override string ToString() { return Name; @@ -339,27 +368,5 @@ throw new InvalidOperationException(Resources.RingtoetsPipingSurfaceLine_SurfaceLine_has_no_Geometry); } } - - /// - /// Checks whether is in range of the . - /// - /// The value to check for. - /// Geometry projected in local coordinate system where the points are ordered on the - /// L-coordinate being monotonically non-decreasing - /// falls outside the L-coordiante span - /// defined by . - public void ValidateInRange(RoundedDouble localCoordinateL, Point2D[] geometryInLocalCoordinates) - { - Point2D firstLocalPoint = geometryInLocalCoordinates.First(); - Point2D lastLocalPoint = geometryInLocalCoordinates.Last(); - if (firstLocalPoint.X > localCoordinateL || lastLocalPoint.X < localCoordinateL) - { - var outOfRangeMessage = string.Format(Resources.RingtoetsPipingSurfaceLine_0_L_needs_to_be_in_1_2_range, - Resources.RingtoetsPipingSurfaceLine_GetZAtL_Cannot_determine_height, - firstLocalPoint.X, - lastLocalPoint.X); - throw new ArgumentOutOfRangeException(null, outOfRangeMessage); - } - } } } \ No newline at end of file