protected static IPolyLine2D CreatePolyline(List <IntPoint> cpolyline, bool containsCircArc, double maxCircArcAngle, bool tryRecoverCircArc = true) { IPolyLine2D polyline; if (containsCircArc && tryRecoverCircArc) { polyline = GeomTools2D.CreatePolyline(CreatePolygon(cpolyline), maxCircArcAngle); } else { var count = cpolyline.Count; polyline = new PolyLine2D(count); if (count > 0) { polyline.StartPoint = new IdaComPoint2D(cpolyline[0].X / ClipperScale, cpolyline[0].Y / ClipperScale); var segments = polyline.Segments; for (int i = 1; i < count; ++i) { segments.Add(new LineSegment2D(new Point(cpolyline[i].X / ClipperScale, cpolyline[i].Y / ClipperScale))); } } } polyline.Close(); return(polyline); }
public static bool TryGetCenterlineOfOpenCFSection(IPolyLine2D outline, double thickness, out IList <IPolyLine2D> centerlines, double tolerance = 0.0001, bool isClosed = true) { int edgeSegmentsCount = 0; centerlines = new List <IPolyLine2D>(); List <Tuple <int, int, Point, Point> > segLst = new List <Tuple <int, int, Point, Point> >(); Point begPt = outline.StartPoint; for (int i = 0, sz = outline.Segments.Count; i < sz; i++) { ISegment2D seg = outline.Segments[i]; IList <ISegment2D> candidates = FindSecondSideOfPlate(begPt, seg, outline, thickness, tolerance); if (!candidates.Any()) { edgeSegmentsCount++; } foreach (ISegment2D candidate in candidates) { int ix = outline.Segments.IndexOf(candidate); Point candidateBegPt = (ix == 0) ? outline.StartPoint : outline.Segments[ix - 1].EndPoint; CreateCenterlineSegment(begPt, seg, candidateBegPt, candidate, out Point clBegPt, out Point clEndPt); segLst.Add(new Tuple <int, int, Point, Point>(i, ix, clBegPt, clEndPt)); } begPt = seg.EndPoint; } if (edgeSegmentsCount != 2) { return(false); } //iterations List <Tuple <Point, Point> > centerlineSegments = new List <Tuple <Point, Point> >(); while (segLst.Any()) { List <Tuple <int, int, Point, Point> > resolved = new List <Tuple <int, int, Point, Point> >(); for (int i = 0, sz = segLst.Count; i < sz; i++) { bool pair = false; Tuple <int, int, Point, Point> seg = segLst[i]; if (resolved.Contains(seg) && isClosed) { continue; } if (i < sz - 1) { if (i > 0) { if (segLst[i - 1].Item1 == seg.Item1) { pair = true; } } if (segLst[i + 1].Item1 == seg.Item1) { pair = true; } } if (!pair) { centerlineSegments.Add(new Tuple <Point, Point>(seg.Item3, seg.Item4)); resolved.Add(seg); Tuple <int, int, Point, Point> secondPart = segLst.FirstOrDefault((item) => item.Item1 == seg.Item2 && item.Item2 == seg.Item1); if (secondPart != null) { resolved.Add(secondPart); int secIx = segLst.IndexOf(secondPart); Tuple <int, int, Point, Point> prev = (secIx == 0) ? null : segLst[secIx - 1]; Tuple <int, int, Point, Point> next = (secIx == segLst.Count - 1) ? null : segLst[secIx + 1]; Tuple <int, int, Point, Point> pairMember = null; if (prev != null) { if (prev.Item1 == secondPart.Item1) { pairMember = prev; } } if (next != null) { if (next.Item1 == secondPart.Item1) { pairMember = next; } } if (pairMember != null) { resolved.Add(pairMember); Tuple <int, int, Point, Point> part3 = segLst.FirstOrDefault((item) => item.Item1 == pairMember.Item2 && item.Item2 == pairMember.Item1); if (part3 != null) { resolved.Add(part3); } } } } } var toBeRemoved = resolved.Distinct(); foreach (Tuple <int, int, Point, Point> remItem in toBeRemoved) { segLst.Remove(remItem); } } if (!centerlineSegments.Any()) { return(false); } List <Tuple <Point, Point> > centerlineOrder = new List <Tuple <Point, Point> >(); centerlineOrder.Add(centerlineSegments.First()); centerlineSegments.Remove(centerlineSegments.First()); bool escape = false; while (centerlineSegments.Any() && !escape) { List <Tuple <Point, Point> > toBeRemoved = new List <Tuple <Point, Point> >(); Tuple <Point, Point> forwardDir = centerlineOrder.Last(); Tuple <Point, Point> backwardDir = centerlineOrder.First(); foreach (Tuple <Point, Point> seg in centerlineSegments) { if (seg.Item1.IsEqualWithTolerance(forwardDir.Item2)) { forwardDir = seg; toBeRemoved.Add(seg); centerlineOrder.Add(seg); } else if (seg.Item2.IsEqualWithTolerance(forwardDir.Item2)) { forwardDir = new Tuple <Point, Point>(seg.Item2, seg.Item1); toBeRemoved.Add(seg); centerlineOrder.Add(forwardDir); } else if (seg.Item2.IsEqualWithTolerance(backwardDir.Item1)) { backwardDir = seg; toBeRemoved.Add(seg); centerlineOrder.Insert(0, seg); } else if (seg.Item1.IsEqualWithTolerance(backwardDir.Item1)) { backwardDir = new Tuple <Point, Point>(seg.Item2, seg.Item1); toBeRemoved.Add(seg); centerlineOrder.Insert(0, backwardDir); } } foreach (Tuple <Point, Point> remItem in toBeRemoved) { centerlineSegments.Remove(remItem); } if (!toBeRemoved.Any()) { Debug.Fail("Nespojitá střednice!! V algoritmu je chyba."); escape = true; } } IPolyLine2D centerline = new PolyLine2D(centerlineOrder.Count); for (int i = 0, sz = centerlineOrder.Count; i < sz; i++) { Tuple <Point, Point> segPts = centerlineOrder[i]; if (i == 0) { centerline.StartPoint = segPts.Item1; } centerline.Segments.Add(new LineSegment2D(segPts.Item2)); } centerlines.Add(centerline); return(true); }
/// <summary> /// Initializes a new instance of the <c>PolyLine2D</c> class as copy of source. /// </summary> /// <param name="source">The source.</param> public PolyLine2D(PolyLine2D source) { StartPoint = source.StartPoint; Segments = (IList <ISegment2D>)source.Segments.Clone(); Id = source.Id; }