Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs =================================================================== diff -u -r5460 -r5477 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs (.../GeometryPointString.cs) (revision 5460) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs (.../GeometryPointString.cs) (revision 5477) @@ -88,7 +88,7 @@ private readonly List points = new List(); private bool isFrozen; private bool hasNaNx; - private double frozenMaxZ = double.NaN; + private readonly double frozenMaxZ = double.NaN; // sortedPoints must never be used outside this class. Either the GPS concerned must have sorted points but then they already are // (eg. surfaceline, headline) or they may be unsorted in which case using the sorted list in other classes leads to errors (eg. @@ -152,27 +152,6 @@ } /// - /// Freezes this instance. - /// - public void Freeze() - { - if (!isFrozen) - { - sortedPoints = new List(calcPoints.Count); - foreach (Point2D point in calcPoints) - { - sortedPoints.Add(point); - hasNaNx = hasNaNx || double.IsNaN(point.X); - frozenMaxZ = Math.Max(frozenMaxZ, point.Z); - } - - sortedPoints.Sort(); - } - - isFrozen = true; - } - - /// /// Clones this object except the points /// /// @@ -195,13 +174,13 @@ /// public void RoundPointsCoordinates(double accuracy) { - foreach (GeometryPoint point in (IEnumerable) this.Points) + foreach (GeometryPoint point in Points) { point.X = RoundValue(point.X, accuracy); point.Z = RoundValue(point.Z, accuracy); } } - + /// /// Gets the minimum z. /// Note: CalcPoints must be used instead of calcPoints as otherwise unclear behaviour of Linq spoils the result @@ -370,42 +349,6 @@ } /// - /// Gets the z at x starting from index i in the point list. - /// This is only meant as a fast(er) version for GetZAtX for lists that are sorted by X, so use with care. - /// - /// The x. - /// The i. - /// - public double GetZatX(double x, ref int i) - { - for (; i < calcPoints.Count - 1; i++) - { - Point2D current = calcPoints[i]; - double leftOffset = x - current.X; - Point2D next = calcPoints[i + 1]; - double rightOffset = next.X - x; - - if (leftOffset < epsilon) - { - return current.Z; - } - - if (rightOffset >= epsilon) - { - double fraction = leftOffset / (leftOffset + rightOffset); - return (1.0 - fraction) * current.Z + fraction * next.Z; - } - - if (i + 1 == calcPoints.Count - 1) - { - return next.Z; - } - } - - return Double.NaN; - } - - /// /// Gets all z-values at x for a line. /// /// The x. @@ -416,16 +359,6 @@ } /// - /// Gets all z values at x for a surface. - /// - /// The x. - /// - public List GetAllZatXForSurface(double x) - { - return GetAllZatX(x, true); - } - - /// /// Finds the first intersection of the line with a given horizontal line. /// /// The height level of the horizontal line. @@ -477,9 +410,9 @@ /// public IEnumerable GetPointsAtX(double x) { - return (from Point2D point in calcPoints - where point.X.AlmostEquals(x, GeometryPoint.Precision) - select point); + return from Point2D point in calcPoints + where point.X.AlmostEquals(x, GeometryPoint.Precision) + select point; } /// @@ -508,36 +441,7 @@ point.Z.AlmostEquals(z, GeometryPoint.Precision)); } - //#Bka: this should never be 1 method! Split it into 2 methods - // It is used for sliplanes only and therefor uses Points instead of calcPoints /// - /// Adds the or remove list object. - /// - /// a point. - /// if set to true [a to add]. - /// a index. - public virtual void AddOrRemoveListObject(object aPoint, bool aToAdd, int aIndex) - { - var point = aPoint as GeometryPoint; - if (point == null) - { - return; - } - - if (aToAdd) - { - Points.Insert(aIndex, point); //#bka what happens if index already exists? what if point exists? What if both??? - } - else - { - if (Points.Contains(point)) - { - Points.Remove(point); - } - } - } - - /// /// Returns ALL intersection points that are found for a line costructed at level z, /// including the double ones as the number of points can be relevant! /// @@ -578,20 +482,6 @@ } /// - /// Find intersection (xz-plane) from this surface with another surface - /// or phratic line - /// - /// - /// - /// Considers all in to - /// such that they describe a closed loop. - /// - public IList ClosedGeometryIntersectionXzPointsWithGeometryPointList(IList list) - { - return IntersectWithPointsListCore(list, true); - } - - /// /// Finds all intersections in the XZ-plane the given . /// /// The geometry point string. @@ -612,79 +502,6 @@ } /// - /// Removes the non ascending points on surface line. - /// - public void RemoveNonAscendingPointsOnSurfaceLine() - { - for (int i = points.Count - 1; i > 0; i--) - { - if (Math.Abs(points[i].X - points[i - 1].X) < GeometryConstants.Accuracy) - { - if (Math.Abs(points[i].Z - points[i - 1].Z) > GeometryConstants.Accuracy) - { - points.Remove(points[i]); - } - } - } - } - - /// - /// Gets a part of the geometry point string defined by a begin and end point - /// - /// - /// - /// - public GeometryPointString GetPart(double begin, double end) - { - var part = new GeometryPointString(); - var filling = false; - var filled = false; - - for (var i = 0; i < calcPoints.Count; i++) - { - if (!filling && !filled) - { - filling = calcPoints[i].X >= begin - epsilon; - } - else - { - filled = calcPoints[i].X >= end - epsilon; - if (filled) - { - filling = false; - } - } - - if (filling) - { - part.calcPoints.Add(calcPoints[i]); - } - } - - var beginPoint = new Point2D(begin, GetZatX(begin)); - var endPoint = new Point2D(end, GetZatX(end)); - - if (part.calcPoints.Count == 0) - { - part.calcPoints.Add(beginPoint); - part.calcPoints.Add(endPoint); - } - - if (!part.calcPoints[0].LocationEquals(beginPoint)) - { - part.calcPoints.Insert(0, beginPoint); - } - - if (!part.calcPoints[part.calcPoints.Count - 1].LocationEquals(endPoint)) - { - part.calcPoints.Add(endPoint); - } - - SyncPoints(); - return part; - } - - /// /// Removes all double points at a location, if consecutive /// public void CondensePoints() @@ -755,6 +572,42 @@ } /// + /// Finds all intersections in the XZ-plane the given list. + /// + /// The list. + /// + /// + public List IntersectionXzPointsWithGeometryPointList(IList list) + { + return IntersectWithPointsListCore(list, false); + } + + /// + /// Determines the relative position of a point to the geometric line in the XZ-plane. + /// + /// + /// + /// + public RelativeXzPosition GetPosition(GeometryLoop geometryLoop, ExtraPolationMode extraPolationMode = ExtraPolationMode.Beyond) + { + foreach (GeometryPoint point in geometryLoop.Points.Concat(GetLoopSegmentMiddlePoints(geometryLoop))) + { + RelativeXzPosition position = PositionXzOfPointRelatedToExtrapolatedLine(point, extraPolationMode); + if (position == RelativeXzPosition.BeyondGeometricLine) + { + position = RelativeXzPosition.BelowGeometricLine; + } + + if (position != RelativeXzPosition.OnGeometricLine) + { + return position; + } + } + + return RelativeXzPosition.OnGeometricLine; + } + + /// /// Gets the surrounding rectangle around the geometry point string /// /// @@ -799,102 +652,90 @@ return intersectionPointsWithLine; } - /// - /// Finds all intersections in the XZ-plane the given list. - /// - /// The list. - /// - /// - /// - public List IntersectionXzPointsWithGeometryPointList(IList list) - { - return IntersectWithPointsListCore(list, false); - } - - /// - /// Determines the relative position of a point to the geometric line in the XZ-plane. - /// - /// - /// - /// - public RelativeXzPosition GetPosition(GeometryLoop geometryLoop, ExtraPolationMode extraPolationMode = ExtraPolationMode.Beyond) - { - foreach (GeometryPoint point in geometryLoop.Points.Concat(GeometryPointString.GetLoopSegmentMiddlePoints(geometryLoop))) - { - RelativeXzPosition position = PositionXzOfPointRelatedToExtrapolatedLine(point, extraPolationMode); - if (position == RelativeXzPosition.BeyondGeometricLine) - position = RelativeXzPosition.BelowGeometricLine; - if (position != RelativeXzPosition.OnGeometricLine) - return position; - } - return RelativeXzPosition.OnGeometricLine; - } - - private RelativeXzPosition PositionXzOfPointRelatedToExtrapolatedLine(GeometryPoint point, + private RelativeXzPosition PositionXzOfPointRelatedToExtrapolatedLine(GeometryPoint point, ExtraPolationMode extraPolationMode = ExtraPolationMode.Beyond) { - return IsPointConsideredBeyondLine(point, extraPolationMode) ? - RelativeXzPosition.BeyondGeometricLine : DeterminePositionWithRespectToExtrapolatedLine(point, extraPolationMode); + return IsPointConsideredBeyondLine(point, extraPolationMode) ? RelativeXzPosition.BeyondGeometricLine : DeterminePositionWithRespectToExtrapolatedLine(point, extraPolationMode); } - + private bool IsPointConsideredBeyondLine(GeometryPoint point, ExtraPolationMode extraPolationMode) { - if (this.Points.Count == 0) + if (Points.Count == 0) + { return true; - return this.IsPointOutsideRangeX(point) && extraPolationMode == ExtraPolationMode.Beyond; + } + + return IsPointOutsideRangeX(point) && extraPolationMode == ExtraPolationMode.Beyond; } - + private bool IsPointOutsideRangeX(GeometryPoint point) { - return point.X < Points[0].X || point.X > Points[checked (Points.Count - 1)].X; + return point.X < Points[0].X || point.X > Points[checked(Points.Count - 1)].X; } - + private RelativeXzPosition DeterminePositionWithRespectToExtrapolatedLine(GeometryPoint point, ExtraPolationMode extraPolationMode) { double xToEvaluate = GetXToEvaluate(point, extraPolationMode); - var zAtX = GetZatX(xToEvaluate); + double zAtX = GetZatX(xToEvaluate); if (Math.Abs(point.Z - zAtX) < 0.001) + { return RelativeXzPosition.OnGeometricLine; + } + return point.Z <= zAtX ? RelativeXzPosition.BelowGeometricLine : RelativeXzPosition.AboveGeometricLine; } - + private double GetXToEvaluate(GeometryPoint point, ExtraPolationMode extraPolationMode) { double x = point.X; if (extraPolationMode == ExtraPolationMode.Horizontal) { if (x < Points[0].X) + { x = Points[0].X; - else if (x > Points[checked (Points.Count - 1)].X) - x = Points[checked (Points.Count - 1)].X; + } + else if (x > Points[checked(Points.Count - 1)].X) + { + x = Points[checked(Points.Count - 1)].X; + } } + return x; } - + private static IEnumerable GetLoopSegmentMiddlePoints(GeometryPointString geometryLoop) { var loopSegmentMiddlePoints = new List(); var index = 0; - while (index < checked (geometryLoop.Points.Count - 1)) + while (index < checked(geometryLoop.Points.Count - 1)) { - AddLoopSegmentMiddlePoint(geometryLoop.Points[index], geometryLoop.Points[checked (index + 1)], loopSegmentMiddlePoints); - checked { ++index; } + AddLoopSegmentMiddlePoint(geometryLoop.Points[index], geometryLoop.Points[checked(index + 1)], loopSegmentMiddlePoints); + checked + { + ++index; + } } + if (geometryLoop.Points.Count > 2) { int last = geometryLoop.Points.Count - 1; AddLoopSegmentMiddlePoint(geometryLoop.Points[0], geometryLoop.Points[last], loopSegmentMiddlePoints); } + return loopSegmentMiddlePoints; } - + private static void AddLoopSegmentMiddlePoint(GeometryPoint point1, GeometryPoint point2, IList loopSegmentMiddlePoints) { if (Math.Abs(point1.Z - point2.Z) < 0.001) + { loopSegmentMiddlePoints.Insert(0, new GeometryPoint((point1.X + point2.X) / 2.0, point1.Z)); + } else + { loopSegmentMiddlePoints.Add(new GeometryPoint((point1.X + point2.X) / 2.0, (point1.Z + point2.Z) / 2.0)); + } } /// @@ -943,6 +784,7 @@ if (calcPoints.Count == 1 && Math.Abs(calcPoints[0].X - x) < epsilon) { result.Add(calcPoints[0].Z); + return result; } int pointsCount = calcPoints.Count - 1;