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); }