/***************************************************/ public static bool IsClockwise(this PolyCurve curve, Vector normal, double tolerance = Tolerance.Distance) { if (!curve.IsClosed(tolerance)) { throw new Exception("The curve is not closed. IsClockwise method is relevant only to closed curves."); } List <Point> cPts = new List <Point> { curve.IStartPoint() }; foreach (ICurve c in curve.SubParts()) { if (c is Line) { cPts.Add(c.IEndPoint()); } else if (c is Arc) { cPts.Add(c.IPointAtParameter(0.5)); cPts.Add(c.IEndPoint()); } else { throw new NotImplementedException(); } } return(IsClockwise(new Polyline { ControlPoints = cPts }, normal, tolerance)); }
/***************************************************/ public static List <PolyCurve> SplitAtPoints(this PolyCurve curve, List <Point> points, double tolerance = Tolerance.Distance) { if (points.Count == 0) { return new List <PolyCurve> { curve.DeepClone() } } ; List <PolyCurve> result = new List <PolyCurve>(); List <ICurve> tmpResult = new List <ICurve>(); List <Point> subPoints = new List <Point>(); List <Point> onCurvePoints = new List <Point>(); foreach (Point p in points) { if (p.IsOnCurve(curve, tolerance)) { onCurvePoints.Add(p); } } onCurvePoints = onCurvePoints.CullDuplicates(tolerance); if (onCurvePoints.Count == 0) { return new List <PolyCurve> { curve.DeepClone() } } ; onCurvePoints = onCurvePoints.SortAlongCurve(curve); foreach (ICurve crv in curve.SubParts()) { if (crv is Arc) { foreach (Point point in onCurvePoints) { if (point.IIsOnCurve(crv, tolerance)) { subPoints.Add(point); } } tmpResult.AddRange((crv as Arc).SplitAtPoints(subPoints)); subPoints.Clear(); } else if (crv is Line) { foreach (Point point in onCurvePoints) { if (point.IIsOnCurve(crv, tolerance)) { subPoints.Add(point); } } tmpResult.AddRange((crv as Line).SplitAtPoints(subPoints)); subPoints.Clear(); } else if (crv is Circle) { List <PolyCurve> tResult = new List <PolyCurve>(); foreach (Arc arc in (crv as Circle).SplitAtPoints(onCurvePoints, tolerance)) { tResult.Add(new PolyCurve { Curves = new List <ICurve> { arc } }); } result.AddRange(tResult); } else { Reflection.Compute.RecordError($"SplitAtPoints is not implemented for PolyCurves consisting of ICurves of type: {crv.GetType().Name}."); return(null); } } int i = 0; int j = 0; if (curve.IStartPoint().IsEqual(onCurvePoints[0])) { onCurvePoints.Add(onCurvePoints[0]); onCurvePoints.RemoveAt(0); } while (i <= onCurvePoints.Count) { List <ICurve> subResultList = new List <ICurve>(); while (j < tmpResult.Count) { subResultList.Add(tmpResult[j]); if (i < onCurvePoints.Count) { if (tmpResult[j].IEndPoint().IsEqual(onCurvePoints[i]) || (curve.IIsClosed(tolerance) && !curve.IIsClockwise(curve.INormal(), tolerance) && tmpResult[j].IStartPoint().IsEqual(onCurvePoints[i]))) { j++; break; } else if (tmpResult[j].IEndPoint().IsEqual(curve.EndPoint()) || (curve.IIsClosed(tolerance) && !curve.IIsClockwise(curve.INormal(), tolerance) && tmpResult[j].IEndPoint().IsEqual(curve.StartPoint()))) { j++; break; } } j++; } if (subResultList.Count > 0) { result.Add(new PolyCurve { Curves = subResultList.ToList() }); } i++; } if (curve.IsClosed(tolerance) && !(curve.SubParts()[0] is Circle)) { if (!curve.StartPoint().IsEqual(onCurvePoints[onCurvePoints.Count - 1])) { List <ICurve> subResultList = new List <ICurve>(); foreach (ICurve subCrv in result[result.Count - 1].ISubParts()) { subResultList.Add(subCrv); } foreach (ICurve subCrv in result[0].ISubParts()) { subResultList.Add(subCrv); } result.RemoveAt(0); result.RemoveAt(result.Count - 1); result.Add(new PolyCurve { Curves = subResultList.ToList() }); } } return(result); }