Exemple #1
0
        /***************************************************/

        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);
        }
Exemple #2
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static PolyCurve SortCurves(this PolyCurve curve, double tolerance = Tolerance.Distance)
        {
            if (curve.Curves.Count < 2)
            {
                return(curve.DeepClone());
            }

            List <ICurve> pending = curve.Curves.Select(x => x.DeepClone()).ToList();
            PolyCurve     result  = new PolyCurve {
                Curves = new List <ICurve> {
                    pending[0]
                }
            };

            pending.RemoveAt(0);

            double sqTol = tolerance * tolerance;

            while (pending.Count > 0)
            {
                Point start1    = result.StartPoint();
                Point end1      = result.EndPoint();
                bool  foundNext = false;

                for (int i = 0; i < pending.Count; i++)
                {
                    Point start2 = pending[i].IStartPoint();
                    Point end2   = pending[i].IEndPoint();

                    if (end1.SquareDistance(start2) < sqTol)
                    {
                        result.Curves.Add(pending[i]);
                        pending.RemoveAt(i);
                        foundNext = true;
                        break;
                    }
                    else if (end1.SquareDistance(end2) < sqTol)
                    {
                        result.Curves.Add(pending[i].IFlip());
                        pending.RemoveAt(i);
                        foundNext = true;
                        break;
                    }
                    else if (start1.SquareDistance(end2) < sqTol)
                    {
                        result.Curves.Insert(0, pending[i]);
                        pending.RemoveAt(i);
                        foundNext = true;
                        break;
                    }
                    else if (start1.SquareDistance(start2) < sqTol)
                    {
                        result.Curves.Insert(0, pending[i].IFlip());
                        pending.RemoveAt(i);
                        foundNext = true;
                        break;
                    }
                }

                if (!foundNext)
                {
                    throw new Exception("PolyCurve with unconnected subcurves cannot have them sorted");
                }
            }

            return(result);
        }