public static IEnumerable <IPolyLine2D> BuildOffset(IEnumerable <IPolyLine2D> polylines, double delta, JoinType joinType, EndType endType, double mitterLimit, bool sort = false, double maxDiscretizationAngle = 5) { PolyLine2DDiscretizator discretizator = new PolyLine2DDiscretizator { NumberOfTiles = 1, LengthOfTile = double.MaxValue, Angle = maxDiscretizationAngle }; bool containsCircArc = joinType == JoinType.jtRound || endType == EndType.etOpenRound; var polygons = new List <List <IntPoint> >(polylines.Count()); foreach (var polyline in polylines) { if (!containsCircArc) { containsCircArc |= polyline.Segments.FirstOrDefault(s => s is CircularArcSegment2D) != null; } var polygon = CreatePolygon(polyline, discretizator, true); polygons.Add(polygon); } var co = new ClipperOffset(mitterLimit); co.AddPaths(polygons, joinType, endType); var solution = new List <List <IntPoint> >(); co.Execute(ref solution, delta * ClipperScale); foreach (var polygon in solution) { yield return(CreatePolyline(polygon, containsCircArc, maxDiscretizationAngle + 1)); } }
protected static List <IntPoint> CreatePolygon(IPolyLine2D polyline, PolyLine2DDiscretizator discretizator, bool counterClockwise) { IPolygon2D polygon = new Polygon2D(); discretizator.Discretize(polyline, ref polygon, null); return(CreatePolygon(polygon, counterClockwise)); }
public static IEnumerable <IPolyLine2D> BuildOffset(IPolyLine2D polyline, double delta, JoinType joinType, EndType endType, double mitterLimit, bool sort = false, double maxDiscretizationAngle = 5) { PolyLine2DDiscretizator discretizator = new PolyLine2DDiscretizator { NumberOfTiles = 1, LengthOfTile = double.MaxValue, Angle = maxDiscretizationAngle }; var p = CreatePolygon(polyline, discretizator, true); bool containsCircArc = joinType == JoinType.jtRound || endType == EndType.etOpenRound; if (!containsCircArc) { containsCircArc = polyline.Segments.FirstOrDefault(s => s is CircularArcSegment2D) != null; } var co = new ClipperOffset(mitterLimit); co.AddPath(p, joinType, endType); var solution = new List <List <IntPoint> >(); co.Execute(ref solution, delta * ClipperScale); if (sort && polyline.IsClosed && !containsCircArc && joinType == JoinType.jtMiter && (endType == EndType.etClosedLine || endType == EndType.etClosedPolygon) && solution.Count == 1) { // try to sort offset path according to source path var newPolyline = CreatePolyline(solution[0], containsCircArc, maxDiscretizationAngle + 1); TrySortSegments(polyline, newPolyline, delta); yield return(newPolyline); } else { foreach (var polygon in solution) { yield return(CreatePolyline(polygon, containsCircArc, maxDiscretizationAngle + 1)); } } }
public static IRegion2D Simplify(IRegion2D region, double maxDiscretizationAngle = 5) { PolyLine2DDiscretizator discretizator = new PolyLine2DDiscretizator { NumberOfTiles = 1, LengthOfTile = double.MaxValue, Angle = maxDiscretizationAngle }; var polyline = region.Outline; var containsCircArc = polyline.Segments.FirstOrDefault(s => s is CircularArcSegment2D) != null; var polygon = CreatePolygon(polyline, discretizator, true); var solution = Clipper.SimplifyPolygon(polygon); if (solution.Count == 1) { var newRegion = new Region2D(CreatePolyline(solution[0], containsCircArc, maxDiscretizationAngle + 1)); foreach (var opening in region.Openings) { containsCircArc = opening.Segments.FirstOrDefault(s => s is CircularArcSegment2D) != null; polygon = CreatePolygon(opening, discretizator, true); solution = Clipper.SimplifyPolygon(polygon); if (solution.Count == 1) { newRegion.Openings.Add(CreatePolyline(solution[0], containsCircArc, maxDiscretizationAngle + 1)); } else { throw new System.NotImplementedException(); } } return(newRegion); } throw new System.NotImplementedException(); }