Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryLoop.cs =================================================================== diff -u -r4000 -r4052 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryLoop.cs (.../GeometryLoop.cs) (revision 4000) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryLoop.cs (.../GeometryLoop.cs) (revision 4052) @@ -22,158 +22,173 @@ using System; using System.Collections.Generic; -namespace Deltares.DamEngine.Data.Geometry +namespace Deltares.DamEngine.Data.Geometry; + +/// +/// Dataclass for the geometryloop. +/// +/// +public class GeometryLoop : GeometryPointString { /// - /// Dataclass for the geometryloop. + /// List of points that describe the physical surface line or surface. /// - /// - public class GeometryLoop : GeometryPointString + /// This property is not serialized. If you want to add point definitions, + /// do so by adding/inserting a new element to . + public override List CalcPoints { - /// - /// List of points that describe the physical surface line or surface. - /// - /// This property is not serialized. If you want to add point definitions, - /// do so by adding/inserting a new element to . - public override List CalcPoints + get { - get + // explicit use of protected field to prevent stack overflow due to recursive call + if (calcPoints.Count == 0) { - // explicit use of protected field to prevent stack overflow due to recursive call - if (calcPoints.Count == 0) - { - PopulateLoopPointList(); - SyncPoints(); - } - - return calcPoints; + PopulateLoopPointList(); + SyncPoints(); } + + return calcPoints; } + } - /// - /// Gets the List of all Curves. - /// - public List CurveList { get; } = new List(); + /// + /// Gets the List of all Curves. + /// + public List CurveList { get; } = new List(); - /// - /// Determines whether this instance is loop. - /// - /// - public bool IsLoop() + /// + /// Determines whether this instance is loop. + /// + /// + public bool IsLoop() + { + if (CurveList.Count <= 2) { - if (CurveList.Count <= 2) - { - return false; - } + return false; + } - GeometryCurve beginCurve = CurveList[0]; - GeometryCurve endCurve = CurveList[CurveList.Count - 1]; + GeometryCurve beginCurve = CurveList[0]; + GeometryCurve endCurve = CurveList[CurveList.Count - 1]; - if (beginCurve.HeadPoint == endCurve.HeadPoint || - beginCurve.HeadPoint == endCurve.EndPoint || - beginCurve.EndPoint == endCurve.HeadPoint || - beginCurve.EndPoint == endCurve.EndPoint) - { - return true; - } + if (beginCurve.HeadPoint == endCurve.HeadPoint || + beginCurve.HeadPoint == endCurve.EndPoint || + beginCurve.EndPoint == endCurve.HeadPoint || + beginCurve.EndPoint == endCurve.EndPoint) + { + return true; + } + return false; + } + + /// + /// Determines whether this instance has area. + /// + /// + public bool HasArea() + { + if (CurveList.Count < 3) + { return false; } - /// - /// Determines whether this instance has area. - /// - /// - public bool HasArea() + // Make sure points from curves are also exist as points + if (CalcPoints.Count > 0) { - if (CurveList.Count < 3) - { - return false; - } + SyncPoints(); + } - // Make sure points from curves are also exist as points - if (CalcPoints.Count > 0) - { - SyncPoints(); - } + var points = new List(); + points.AddRange(Points); + points.Add(points[0]); - var points = new List(); - points.AddRange(Points); - points.Add(points[0]); + // Calculate area of polygon using Shoelace algorithm: + var sum = 0.0; + for (var i = 1; i < points.Count; i++) + { + sum += points[i - 1].X * points[i].Z - points[i - 1].Z * points[i].X; + } - // Calculate area of polygon using Shoelace algorithm: - var sum = 0.0; - for (var i = 1; i < points.Count; i++) - { - sum += points[i - 1].X * points[i].Z - points[i - 1].Z * points[i].X; - } + return Math.Abs(sum) > 1e-6; + } - return Math.Abs(sum) > 1e-6; + /// + /// Determines whether [is clock wise]. + /// + /// + /// + /// Cannot determine if loop is clockwise if checked location forms a straight line with its neighboring vectors. + public bool IsClockWise() + { + List polyGon = GetLocalPoint2DList(); + Clockwise isClockWise = Routines2D.IsClockWise(polyGon); + if (isClockWise == Clockwise.NotEnoughUniquePoints) + { + throw new NotEnoughUniquePointsException(); } - /// - /// Determines whether [is clock wise]. - /// - /// - /// - /// Cannot determine if loop is clockwise if checked location forms a straight line with its neighboring vectors. - public bool IsClockWise() + if (isClockWise == Clockwise.PointsOnLine) { - List polyGon = GetLocalPoint2DList(); - Clockwise isClockWise = Routines2D.IsClockWise(polyGon); - if (isClockWise == Clockwise.NotEnoughUniquePoints) - { - throw new NotEnoughUniquePointsException(); - } + throw new InvalidOperationException("Cannot determine if loop is clockwise if checked location forms a straight line with its neighboring vectors."); + } - if (isClockWise == Clockwise.PointsOnLine) - { - throw new InvalidOperationException("Cannot determine if loop is clockwise if checked location forms a straight line with its neighboring vectors."); - } + return isClockWise == Clockwise.IsClockwise; + } - return isClockWise == Clockwise.IsClockwise; - } + /// + /// See if a point lies in a closed surface + /// + /// + /// + public bool IsPointInLoopArea(Point2D aPoint) + { + return Routines2D.CheckIfPointIsInPolygon(this, aPoint.X, aPoint.Z) != PointInPolygon.OutsidePolygon; + } - /// - /// See if a point lies in a closed surface - /// - /// - /// - public bool IsPointInLoopArea(Point2D aPoint) - { - return Routines2D.CheckIfPointIsInPolygon(this, aPoint.X, aPoint.Z) != PointInPolygon.OutsidePolygon; - } + /// + /// Gets the local 2D Points List. + /// + /// + private List GetLocalPoint2DList() + { + return CalcPoints; + } - /// - /// Gets the local 2D Points List. - /// - /// - private List GetLocalPoint2DList() + /// + /// Populates the loop's GeometryPoint list. + /// + private void PopulateLoopPointList() + { + // explicit use of protected field to prevent stack overflow due to recursive call + if (calcPoints.Count > 0) { - return CalcPoints; + return; } - /// - /// Populates the loop's GeometryPoint list. - /// - private void PopulateLoopPointList() + for (var index = 0; index < CurveList.Count; index++) { - // explicit use of protected field to prevent stack overflow due to recursive call - if (calcPoints.Count > 0) + if (index == 0) { - return; + calcPoints.Add(CurveList[index].HeadPoint); + calcPoints.Add(CurveList[index].EndPoint); } - - for (var index = 0; index < CurveList.Count; index++) + else { - if (index == 0) + // TODO why not compare by value instead of reference + if (CurveList[index].HeadPoint == calcPoints[calcPoints.Count - 1]) { - calcPoints.Add(CurveList[index].HeadPoint); calcPoints.Add(CurveList[index].EndPoint); } + else if (CurveList[index].EndPoint == calcPoints[calcPoints.Count - 1]) + { + calcPoints.Add(CurveList[index].HeadPoint); + } else { - // TODO why not compare by value instead of reference + if (calcPoints.Count == 2) + { + calcPoints.Reverse(); + } + if (CurveList[index].HeadPoint == calcPoints[calcPoints.Count - 1]) { calcPoints.Add(CurveList[index].EndPoint); @@ -182,44 +197,28 @@ { calcPoints.Add(CurveList[index].HeadPoint); } - else - { - if (calcPoints.Count == 2) - { - calcPoints.Reverse(); - } - - if (CurveList[index].HeadPoint == calcPoints[calcPoints.Count - 1]) - { - calcPoints.Add(CurveList[index].EndPoint); - } - else if (CurveList[index].EndPoint == calcPoints[calcPoints.Count - 1]) - { - calcPoints.Add(CurveList[index].HeadPoint); - } - } } } + } - if (calcPoints.Count > 0) + if (calcPoints.Count > 0) + { + if (calcPoints[0] == calcPoints[calcPoints.Count - 1]) { - if (calcPoints[0] == calcPoints[calcPoints.Count - 1]) - { - calcPoints.RemoveAt(calcPoints.Count - 1); - } + calcPoints.RemoveAt(calcPoints.Count - 1); } } + } + /// + /// Helper class NotEnoughUniquePointsException + /// + public class NotEnoughUniquePointsException : InvalidOperationException + { /// - /// Helper class NotEnoughUniquePointsException + /// Initializes a new instance of the class. /// - public class NotEnoughUniquePointsException : InvalidOperationException - { - /// - /// Initializes a new instance of the class. - /// - public NotEnoughUniquePointsException() - : base("At least 3 unique points are required to determine if the loop is running clockwise.") {} - } + public NotEnoughUniquePointsException() + : base("At least 3 unique points are required to determine if the loop is running clockwise.") {} } } \ No newline at end of file