public static Polygon PolygonWithPolygon(Polygon polygon) { Polygon rootPolygon = null; // Compose with sub-olygons (if any). polygon.EnumeratePolygons((Polygon eachPolygon) => { if (rootPolygon == null) { rootPolygon = Polygon.PolygonWithPoints(eachPolygon.points); } else { rootPolygon.AddPolygon(Polygon.PolygonWithPoints(eachPolygon.points)); } }); return(rootPolygon); }
public static Polygon PolygonWithPointTransforms(Transform[] pointTransforms, Source.Polygon.Coordinates coordinates) { // Create points array. Vector2[] points = new Vector2[pointTransforms.Length]; for (int index = 0; index < pointTransforms.Length; index++) { Transform eachPointTransform = pointTransforms[index]; if (coordinates == Source.Polygon.Coordinates.World) { points[index] = eachPointTransform.position.xy(); } if (coordinates == Source.Polygon.Coordinates.Local) { points[index] = eachPointTransform.localPosition.xy(); } } return(Polygon.PolygonWithPoints(points)); }
public static Polygon PolygonWithPointList(List <Vector2> pointList) { return(Polygon.PolygonWithPoints(pointList.ToArray())); }
public Polygon UnionPolygon() { // Calculate Polygon-Clipper scale. float maximum = Mathf.Max(bounds.width, bounds.height); float maximumScale = (float)Int32.MaxValue / maximum; float scale = Mathf.Min(clipperScale, maximumScale); // Convert to Clipper. Paths subjectPaths = new Paths(); Paths clipPaths = new Paths(); { Path path = new Path(); EnumeratePoints((Vector2 eachPoint) => { path.Add(new IntPoint(eachPoint.x * scale, eachPoint.y * scale)); }); subjectPaths.Add(path); } foreach (Polygon eachPolygon in polygons) { Path path = new Path(); eachPolygon.EnumeratePoints((Vector2 eachPoint) => { path.Add(new IntPoint(eachPoint.x * scale, eachPoint.y * scale)); }); clipPaths.Add(path); } // Clipper union. Paths unionPaths = new Paths(); Clipper clipper = new Clipper(); clipper.AddPaths(subjectPaths, PolyType.ptSubject, true); clipper.AddPaths(clipPaths, PolyType.ptClip, true); clipper.Execute(ClipType.ctUnion, unionPaths); // Remove self intersections. Paths simplifiedUnionPaths = new Paths(); simplifiedUnionPaths = Clipper.SimplifyPolygons(unionPaths); // Convert from Cipper. Polygon simplifiedUnionPolygon = null; for (int index = 0; index < simplifiedUnionPaths.Count; index++) { Path eachSolutionPath = simplifiedUnionPaths[index]; Polygon eachSolutionPolygon = PolygonFromClipperPath(eachSolutionPath, scale); if (index == 0) { simplifiedUnionPolygon = Polygon.PolygonWithPoints(eachSolutionPolygon.points); // Copy } else { simplifiedUnionPolygon.AddPolygon(eachSolutionPolygon); } } // Back to Polygon. return(simplifiedUnionPolygon); }
Polygon OffsetPolygon(float offset, bool simplify, bool rounded) { // Calculate Polygon-Clipper scale. float maximum = Mathf.Max(bounds.width, bounds.height) + offset * 2.0f + offset; float maximumScale = (float)Int32.MaxValue / maximum; float scale = Mathf.Min(clipperScale, maximumScale); // Convert to Clipper. Paths paths = new Paths(); { Path path = new Path(); EnumeratePoints((Vector2 eachPoint) => { path.Add(new IntPoint(eachPoint.x * scale, eachPoint.y * scale)); }); paths.Add(path); } foreach (Polygon eachPolygon in polygons) { Path path = new Path(); eachPolygon.EnumeratePoints((Vector2 eachPoint) => { path.Add(new IntPoint(eachPoint.x * scale, eachPoint.y * scale)); }); paths.Add(path); } // Mode. JoinType joinType = (rounded) ? JoinType.jtRound : JoinType.jtMiter; // Clipper offset. Paths offsetPaths = new Paths(); ClipperOffset clipperOffset = new ClipperOffset(); if (rounded) { clipperOffset.ArcTolerance = 0.25 * clipperArcTolerance; } // "The default ArcTolerance is 0.25 units." from http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/Properties/ArcTolerance.htm clipperOffset.AddPaths(paths, joinType, EndType.etClosedPolygon); clipperOffset.Execute(ref offsetPaths, (double)offset * scale); // Remove self intersections (if requested). if (simplify) { offsetPaths = Clipper.SimplifyPolygons(offsetPaths); } // Convert from Clipper. Polygon offsetPolygon = null; for (int index = 0; index < offsetPaths.Count; index++) { Path eachSolutionPath = offsetPaths[index]; Polygon eachSolutionPolygon = PolygonFromClipperPath(eachSolutionPath, scale); if (index == 0) { offsetPolygon = Polygon.PolygonWithPoints(eachSolutionPolygon.points); // Copy } else { offsetPolygon.AddPolygon(eachSolutionPolygon); } } // Back to Polygon. return(offsetPolygon); }