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);
        }
Example #2
0
        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);
        }
Example #3
0
 /// <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;
 }