Ejemplo n.º 1
0
        public static List <Point> PointLayout(this PerimeterLayout layout2D, IEnumerable <ICurve> hostRegionCurves, IEnumerable <ICurve> openingCurves = null)
        {
            List <ICurve> regionCurveList = hostRegionCurves.ToList();
            List <int>    divs            = new List <int>();

            if (regionCurveList.Count == 1)
            {
                divs.Add(layout2D.NumberOfPoints);
            }
            else
            {
                divs = DistributeDivisions(regionCurveList, layout2D.NumberOfPoints);
            }

            List <Point> result = new List <Point>();

            for (int j = 0; j < regionCurveList.Count; j++)
            {
                ICurve regionCurve = regionCurveList[j];
                int    curveDivs   = divs[j];

                List <ICurve> subCurves = regionCurve.ISubParts().ToList();
                if (layout2D.EnforceDiscontinuityPoints && subCurves.Count != 1)
                {
                    List <Point> pts = regionCurve.IDiscontinuityPoints();
                    pts.Add(regionCurve.IStartPoint());
                    pts.Add(regionCurve.IEndPoint());
                    pts = pts.CullDuplicates();
                    int remainingPoints = curveDivs - pts.Count;
                    if (remainingPoints > 0)
                    {
                        List <int> divisions = DistributeDivisions(subCurves, remainingPoints);
                        for (int i = 0; i < subCurves.Count; i++)
                        {
                            if (divisions[i] == 0)
                            {
                                continue;
                            }

                            //Sample points always includes start and end (which are removed later) and gives back 1 more point than divisions.
                            //To make sure point(s) on the middle of the are extracted, division is increased by 1, which should return 2 more points than divisions asked for.
                            int div = divisions[i] + 1;

                            List <Point> subPts = subCurves[i].SamplePoints(div);

                            //Remove points at start/end
                            subPts.RemoveAt(subPts.Count - 1);
                            subPts.RemoveAt(0);
                            pts.AddRange(subPts);
                        }
                    }
                    int count = pts.Count;
                    pts = pts.ISortAlongCurve(regionCurve);

                    //SortAlongCurve might add extra points, generally duplicate of start and end point for closed curves.
                    if (pts.Count == count + 1 && pts[0].Distance(pts[pts.Count - 1]) < Tolerance.Distance)
                    {
                        pts.RemoveAt(pts.Count - 1);
                    }
                    else if (pts.Count > count)
                    {
                        pts = pts.CullDuplicates();
                    }

                    result.AddRange(pts);
                }
                else
                {
                    if (curveDivs == 0)
                    {
                        continue;
                    }
                    if (curveDivs == 1)
                    {
                        result.Add(regionCurve.IPointAtParameter(0.5));
                    }
                    else
                    {
                        int  divisions = curveDivs;
                        bool closed    = regionCurve.IIsClosed();

                        if (!closed)
                        {
                            divisions--;
                        }

                        List <Point> pts = regionCurve.SamplePoints(divisions);

                        //Remove duplicate endpoint
                        if (closed)
                        {
                            pts.RemoveAt(pts.Count - 1);
                        }

                        result.AddRange(pts);
                    }
                }
            }

            return(result);
        }
        /***************************************************/

        private static int LayoutCount(PerimeterLayout layout)
        {
            return(layout.NumberOfPoints);
        }