Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs
===================================================================
diff -u -r3893 -r4000
--- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs (.../GeometryPointString.cs) (revision 3893)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs (.../GeometryPointString.cs) (revision 4000)
@@ -35,16 +35,19 @@
/// Indicates that the object is considered 'on' the geometric line.
///
OnGeometricLine,
+
///
/// Indicates that the object is considered 'above' the geometric line (object Z
/// coordinate higher than that of the line).
///
AboveGeometricLine,
+
///
/// Indicates that the object is considered 'below' the geometric line (object Z
/// coordinates lower than that of the line).
///
BelowGeometricLine,
+
///
/// Indicates that the object is considered 'outside the scope' of the geometric line.
///
@@ -60,6 +63,7 @@
/// No extrapolation should be used.
///
Beyond,
+
///
/// Used constant (0th order) extrapolation at the extremes.
///
@@ -75,11 +79,13 @@
/// Matching distance where a point within this range is considered on the same point.
///
private const double epsilon = GeometryConstants.Accuracy;
- private readonly List points = new List();
+
///
/// The calculate points as protected field (to be able to prevent recursive calls to CalcPoints)
///
protected readonly List calcPoints = new List();
+
+ private readonly List points = new List();
private bool isFrozen;
private bool hasNaNx;
private double frozenMaxZ = double.NaN;
@@ -90,33 +96,31 @@
private List sortedPoints;
///
- /// The calculate points (to be used in calcualtion instead of Points for better performance)
+ /// Gets the at the specified index.
///
- public virtual List CalcPoints
+ ///
+ /// The .
+ ///
+ /// The index.
+ /// When less
+ /// than zero or is greater or equals to .
+ public Point2D this[int index]
{
get
{
- return calcPoints;
+ return calcPoints[index];
}
}
-
+
///
- /// Freezes this instance.
+ /// The calculate points (to be used in calcualtion instead of Points for better performance)
///
- public void Freeze()
+ public virtual List CalcPoints
{
- if (!isFrozen)
+ get
{
- 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();
+ return calcPoints;
}
- isFrozen = true;
}
///
@@ -134,37 +138,40 @@
}
///
- /// Gets the at the specified index.
+ /// Gets the count of the points.
///
///
- /// The .
+ /// The count.
///
- /// The index.
- /// When less
- /// than zero or is greater or equals to .
- public Point2D this[int index]
+ public int Count
{
get
{
- return calcPoints[index];
+ return calcPoints.Count;
}
}
///
- /// Gets the count of the points.
+ /// Freezes this instance.
///
- ///
- /// The count.
- ///
- public int Count
+ public void Freeze()
{
- get
+ if (!isFrozen)
{
- return calcPoints.Count;
+ 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
///
@@ -174,10 +181,11 @@
var clone = new GeometryPointString();
this.CloneProperties(clone); // exludes the points !
clone.Points.Clear();
- foreach (var point in Points)
+ foreach (GeometryPoint point in Points)
{
clone.Points.Add(new GeometryPoint(point));
}
+
clone.SyncCalcPoints();
return clone;
}
@@ -203,7 +211,11 @@
///
public double GetMaxZ()
{
- if (isFrozen) return frozenMaxZ;
+ if (isFrozen)
+ {
+ return frozenMaxZ;
+ }
+
return CalcPoints.Any()
? CalcPoints.Max(p => p.Z)
: double.NaN;
@@ -217,7 +229,11 @@
/// The minimal X value or in case there are no points.
public double GetMinX()
{
- if (isFrozen && !hasNaNx) return sortedPoints[0].X;
+ if (isFrozen && !hasNaNx)
+ {
+ return sortedPoints[0].X;
+ }
+
return CalcPoints.Any(p => !double.IsNaN(p.X))
? CalcPoints.Where(p => !double.IsNaN(p.X)).Min(p => p.X)
: double.NaN;
@@ -231,7 +247,11 @@
///
public double GetMaxX()
{
- if (isFrozen && !hasNaNx) return sortedPoints[sortedPoints.Count - 1].X;
+ if (isFrozen && !hasNaNx)
+ {
+ return sortedPoints[sortedPoints.Count - 1].X;
+ }
+
return CalcPoints.Any(p => !double.IsNaN(p.X))
? CalcPoints.Where(p => !double.IsNaN(p.X)).Max(p => p.X)
: double.NaN;
@@ -253,14 +273,23 @@
{
if (calcPoints.Count > 0)
{
- var verticalLineAtX = new Line(new Point2D {X = x, Z= GetMaxZ()},
- new Point2D { X = x, Z = GetMinZ() });
+ var verticalLineAtX = new Line(new Point2D
+ {
+ X = x,
+ Z = GetMaxZ()
+ },
+ new Point2D
+ {
+ X = x,
+ Z = GetMinZ()
+ });
if (Math.Abs(verticalLineAtX.BeginPoint.Z - verticalLineAtX.EndPoint.Z) < GeometryConstants.Accuracy)
{
verticalLineAtX.BeginPoint.Z += 1.0;
verticalLineAtX.EndPoint.Z -= 1.0;
}
- var intersectionPoints = IntersectionPointsXzWithLineXz(verticalLineAtX);
+
+ IList intersectionPoints = IntersectionPointsXzWithLineXz(verticalLineAtX);
if (intersectionPoints.Count != 0)
{
return intersectionPoints.Max(gp => gp.Z);
@@ -273,6 +302,7 @@
return zAtX;
}
}
+
return double.NaN;
}
@@ -297,25 +327,28 @@
return zAtX;
}
}
- for (int i = 0; i < calcPoints.Count - 1; i++)
+
+ for (var i = 0; i < calcPoints.Count - 1; i++)
{
- var current = calcPoints[i];
- var next = calcPoints[i + 1];
+ Point2D current = calcPoints[i];
+ Point2D next = calcPoints[i + 1];
- var leftOffset = x - current.X;
- var rightOffset = next.X - x;
+ double leftOffset = x - current.X;
+ double rightOffset = next.X - x;
if (Math.Abs(leftOffset) < epsilon)
{
return current.Z;
}
+
if (Math.Abs(rightOffset) < epsilon)
{
return next.Z;
}
+
if (leftOffset >= 0 && rightOffset >= 0)
{
- var fraction = leftOffset / (leftOffset + rightOffset);
+ double fraction = leftOffset / (leftOffset + rightOffset);
return (1.0 - fraction) * current.Z + fraction * next.Z;
}
@@ -335,20 +368,22 @@
{
for (; i < calcPoints.Count - 1; i++)
{
- var current = calcPoints[i];
- var leftOffset = x - current.X;
- var next = calcPoints[i + 1];
- var rightOffset = next.X - x;
+ 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)
{
- var fraction = leftOffset / (leftOffset + rightOffset);
+ double fraction = leftOffset / (leftOffset + rightOffset);
return (1.0 - fraction) * current.Z + fraction * next.Z;
}
+
if (i + 1 == calcPoints.Count - 1)
{
return next.Z;
@@ -405,15 +440,15 @@
{
for (int i = start; i < calcPoints.Count - 1; i++)
{
- var current = calcPoints[i];
- var next = calcPoints[i + 1];
+ Point2D current = calcPoints[i];
+ Point2D next = calcPoints[i + 1];
if (IsSegmentNotCrossingZ(z, current, next)) // Performance micro-optimization
{
continue;
}
- var x = GetXIntersectingZ(z, current, next);
+ double x = GetXIntersectingZ(z, current, next);
if (x > xmin)
{
return x;
@@ -485,7 +520,7 @@
{
if (Points.Contains(point))
{
- Points.Remove(point);
+ Points.Remove(point);
}
}
}
@@ -530,20 +565,6 @@
return IntersectionPointsWithLineCore(line, false);
}
- private IList IntersectionPointsXzClosedStringWithLineXz(Line line)
- {
- IList intersectionPointsWithLine = IntersectionPointsXzWithLineXz(line);
-
- // close the poly line
- if (calcPoints.Count > 0)
- {
- DoIntersectAndAddToCollection(line, calcPoints[calcPoints.Count - 1], calcPoints[0],
- intersectionPointsWithLine, false);
- }
-
- return intersectionPointsWithLine;
- }
-
///
/// Find intersection (xz-plane) from this surface with another surface
/// or phratic line
@@ -559,18 +580,6 @@
}
///
- /// Finds all intersections in the XZ-plane the given list.
- ///
- /// The list.
- ///
- ///
- ///
- private List IntersectionXzPointsWithGeometryPointList(IList list)
- {
- return IntersectWithPointsListCore(list, false);
- }
-
- ///
/// Finds all intersections in the XZ-plane the given .
///
/// The geometry point string.
@@ -616,10 +625,10 @@
public GeometryPointString GetPart(double begin, double end)
{
var part = new GeometryPointString();
- bool filling = false;
- bool filled = false;
+ var filling = false;
+ var filled = false;
- for (int i = 0; i < calcPoints.Count; i++)
+ for (var i = 0; i < calcPoints.Count; i++)
{
if (!filling && !filled)
{
@@ -658,6 +667,7 @@
{
part.calcPoints.Add(endPoint);
}
+
SyncPoints();
return part;
}
@@ -699,6 +709,40 @@
}
///
+ /// Synchronizes the calculation points.
+ ///
+ public void SyncCalcPoints()
+ {
+ calcPoints.Clear();
+ foreach (GeometryPoint geometryPoint in Points)
+ {
+ var p2D = new Point2D
+ {
+ X = geometryPoint.X,
+ Z = geometryPoint.Z
+ };
+ calcPoints.Add(p2D);
+ }
+ }
+
+ ///
+ /// Synchronizes the points.
+ ///
+ public void SyncPoints()
+ {
+ points.Clear();
+ foreach (Point2D p2D in calcPoints)
+ {
+ var geometryPoint = new GeometryPoint
+ {
+ X = p2D.X,
+ Z = p2D.Z
+ };
+ points.Add(geometryPoint);
+ }
+ }
+
+ ///
/// Gets the surrounding rectangle around the geometry point string
///
///
@@ -709,7 +753,10 @@
// Sync with calcPoints
SyncPoints();
// if still no points, then return null
- if (!Points.Any()) return null;
+ if (!Points.Any())
+ {
+ return null;
+ }
}
GeometryBounds bounds = Points[0].GetGeometryBounds();
@@ -726,7 +773,33 @@
return bounds;
}
+ private IList IntersectionPointsXzClosedStringWithLineXz(Line line)
+ {
+ IList intersectionPointsWithLine = IntersectionPointsXzWithLineXz(line);
+
+ // close the poly line
+ if (calcPoints.Count > 0)
+ {
+ DoIntersectAndAddToCollection(line, calcPoints[calcPoints.Count - 1], calcPoints[0],
+ intersectionPointsWithLine, false);
+ }
+
+ return intersectionPointsWithLine;
+ }
+
///
+ /// Finds all intersections in the XZ-plane the given list.
+ ///
+ /// The list.
+ ///
+ ///
+ ///
+ private List IntersectionXzPointsWithGeometryPointList(IList list)
+ {
+ return IntersectWithPointsListCore(list, false);
+ }
+
+ ///
/// Checks if constant extrapolation can be applied, and if so set the Z value.
///
/// The evaluated X coordinate.
@@ -737,14 +810,14 @@
{
if (calcPoints.Count > 0)
{
- var first = calcPoints[0];
+ Point2D first = calcPoints[0];
if (x < first.X || Math.Abs(x - first.X) < epsilon)
{
z = first.Z;
return true;
}
- var last = calcPoints[calcPoints.Count - 1];
+ Point2D last = calcPoints[calcPoints.Count - 1];
if (x > last.X)
{
z = last.Z;
@@ -774,12 +847,13 @@
result.Add(calcPoints[0].Z);
}
- var pointsCount = calcPoints.Count - 1;
+ int pointsCount = calcPoints.Count - 1;
if (asSurface)
{
pointsCount = calcPoints.Count;
}
- for (int i = 0; i < pointsCount; i++)
+
+ for (var i = 0; i < pointsCount; i++)
{
Point2D current;
Point2D next;
@@ -794,33 +868,35 @@
next = calcPoints[i + 1];
}
- var leftOffset = x - current.X;
- var rightOffset = next.X - x;
+ double leftOffset = x - current.X;
+ double rightOffset = next.X - x;
var matchedWithAPoint = false;
if (Math.Abs(leftOffset) < epsilon)
{
result.Add(current.Z);
matchedWithAPoint = true;
}
+
if (Math.Abs(rightOffset) < epsilon)
{
result.Add(next.Z);
matchedWithAPoint = true;
}
+
if (!matchedWithAPoint)
{
if (leftOffset > 0 && rightOffset > 0)
{
- var fraction = leftOffset / (leftOffset + rightOffset);
+ double fraction = leftOffset / (leftOffset + rightOffset);
result.Add((1.0 - fraction) * current.Z + fraction * next.Z);
}
// if both ofsets are negative the waterline goes back
if ((leftOffset < 0) && (rightOffset < 0))
{
- var fraction = rightOffset / (rightOffset + leftOffset);
+ double fraction = rightOffset / (rightOffset + leftOffset);
result.Add((1.0 - fraction) * next.Z + fraction * current.Z);
}
@@ -837,8 +913,8 @@
return true;
}
- var leftOffset = Math.Abs(current.Z - z);
- var rightOffset = Math.Abs(next.Z - z);
+ double leftOffset = Math.Abs(current.Z - z);
+ double rightOffset = Math.Abs(next.Z - z);
int currentSign = leftOffset < epsilon ? 0 : Math.Sign(current.Z - z);
int nextSign = rightOffset < epsilon ? 0 : Math.Sign(next.Z - z);
@@ -847,40 +923,42 @@
private static double GetXIntersectingZ(double z, Point2D current, Point2D next)
{
- var leftOffset = Math.Abs(current.Z - z);
+ double leftOffset = Math.Abs(current.Z - z);
if (leftOffset < epsilon)
{
return current.X;
}
- var rightOffset = Math.Abs(next.Z - z);
+
+ double rightOffset = Math.Abs(next.Z - z);
if (rightOffset < epsilon)
{
return next.X;
}
- var fraction = leftOffset / (leftOffset + rightOffset);
+ double fraction = leftOffset / (leftOffset + rightOffset);
return GeneralMathRoutines.LinearInterpolate(current.X, next.X, fraction);
}
private IList IntersectionPointsWithLineCore(Line line, bool allowDuplicates)
{
var intersectionPointsWithLine = new List();
- for (int pointIndex = 0; pointIndex < calcPoints.Count - 1; pointIndex++)
+ for (var pointIndex = 0; pointIndex < calcPoints.Count - 1; pointIndex++)
{
- DoIntersectAndAddToCollection(line, calcPoints[pointIndex], calcPoints[pointIndex + 1],
- intersectionPointsWithLine, allowDuplicates);
+ DoIntersectAndAddToCollection(line, calcPoints[pointIndex], calcPoints[pointIndex + 1],
+ intersectionPointsWithLine, allowDuplicates);
}
+
return intersectionPointsWithLine;
}
private static void DoIntersectAndAddToCollection(Line line, Point2D begin, Point2D end, ICollection intersectionPointsWithLine, bool allowDuplicates)
{
var lineInPoly = new Line
- {
- BeginPoint = begin,
- EndPoint = end
- };
+ {
+ BeginPoint = begin,
+ EndPoint = end
+ };
Point2D intersectionPoint = lineInPoly.GetIntersectPointXz(line);
if (intersectionPoint != null && (allowDuplicates || NoPointSameXzLocation(intersectionPointsWithLine, intersectionPoint)))
{
@@ -891,15 +969,15 @@
private static bool NoPointSameXzLocation(IEnumerable collection, Point2D point)
{
return !collection.Any(
- p => Math.Abs(p.X - point.X) < GeometryConstants.Accuracy &&
- Math.Abs(p.Z - point.Z) < GeometryConstants.Accuracy);
+ p => Math.Abs(p.X - point.X) < GeometryConstants.Accuracy &&
+ Math.Abs(p.Z - point.Z) < GeometryConstants.Accuracy);
}
private List IntersectWithPointsListCore(IList list, bool closePointString)
{
var result = new List();
var line = new Line();
- for (int externalPointIndex = 0; externalPointIndex < list.Count - 1; externalPointIndex++)
+ for (var externalPointIndex = 0; externalPointIndex < list.Count - 1; externalPointIndex++)
{
line.BeginPoint = list[externalPointIndex];
line.EndPoint = list[externalPointIndex + 1];
@@ -911,41 +989,5 @@
return result;
}
-
- ///
- /// Synchronizes the calculation points.
- ///
- public void SyncCalcPoints()
- {
- calcPoints.Clear();
- foreach (var geometryPoint in Points)
- {
- var p2D = new Point2D
- {
- X = geometryPoint.X,
- Z = geometryPoint.Z
-
- };
- calcPoints.Add(p2D);
- }
- }
-
- ///
- /// Synchronizes the points.
- ///
- public void SyncPoints()
- {
- points.Clear();
- foreach (var p2D in calcPoints)
- {
- var geometryPoint = new GeometryPoint
- {
- X = p2D.X,
- Z = p2D.Z
-
- };
- points.Add(geometryPoint);
- }
- }
}
}
\ No newline at end of file