// Copyright (C) Stichting Deltares 2019. All rights reserved. // // This file is part of the Dam Engine. // // The Dam Engine is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero 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.Collections.Generic; namespace Deltares.DamEngine.Data.Geometry { /// /// Dataclass for the geometryloop. /// /// public class GeometryLoop : GeometryPointString { private readonly List curveList = new List(); /// /// Gets the List of all Curves. /// public List CurveList { get { return curveList; } } /// /// 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 { // explicit use of protected field to prevent stack overflow due to recursive call if (calcPoints.Count == 0) { PopulateLoopPointList(); SyncPoints(); } return calcPoints; } } /// /// Determines whether this instance is loop. /// /// public bool IsLoop() { if (CurveList.Count <= 2) { return false; } 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; } return false; } /// /// See if a point lies in a closed surface /// /// /// public bool IsPointInLoopArea(Point2D aPoint) { return Routines2D.CheckIfPointIsInPolygon(this, aPoint.X, aPoint.Z) != PointInPolygon.OutsidePolygon; } /// /// 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; } for (int index = 0; index < curveList.Count; index++) { if (index == 0) { calcPoints.Add(curveList[index].HeadPoint); calcPoints.Add(curveList[index].EndPoint); } else { // TODO why not compare by value instead of reference 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); } 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[0] == calcPoints[calcPoints.Count - 1]) { calcPoints.RemoveAt(calcPoints.Count - 1); } } } } }