public static bool addSteinerPointsAtOffset(ref Polygon _polygon, ref ClipperOffset co, float offset, int seglenBigInt) { PolyTree resPolytree = new AXClipperLib.PolyTree(); co.Execute(ref resPolytree, (double)(-offset * AXGeometryTools.Utilities.IntPointPrecision)); Paths paths = Clipper.PolyTreeToPaths(resPolytree); if (paths != null && paths.Count > 0 && paths[0] != null && paths[0].Count > 0) { foreach (Path path in paths) { if (path != null && path.Count > 0) { Path ppp = Pather.segmentPath(path, seglenBigInt); if (ppp != null && ppp.Count > 0) { foreach (IntPoint ip in ppp) { _polygon.AddSteinerPoint(new TriangulationPoint((double)ip.X / (double)AXGeometryTools.Utilities.IntPointPrecision, (double)ip.Y / (double)AXGeometryTools.Utilities.IntPointPrecision)); } } } } return(true); } return(false); }
/// <summary> /// Add inner steiner points (for coly polygons) /// </summary> /// <param name="points"></param> public void AddSteiner(SplineLines.Line points) { for (int i = 0; i < points.polyPoints.Count; ++i) { polygon.AddSteinerPoint(points.polyPoints[i]); } this.data.Add(points); }
/// <summary> /// Creates a triangulation of the vertices given, and gives you the indices of it. /// </summary> /// <param name="aPoints">A list of points to triangulate.</param> /// <param name="aTreatAsPath">Should we discard any triangles at all? Use this if you want to get rid of triangles that are outside the path.</param> /// <param name="aInvert">if we're treating it as a path, should we instead sicard triangles inside the path?</param> /// <returns>A magical list of indices describing the triangulation!</returns> /// public static void GetVerticesAndIndices(List <Vector2> inputPoints, out List <Vector2> outputPoints, out List <int> outputIndices, float chunkWidth, float chunkHeight, float jitterX, float jitterY) { Polygon poly; List <PolygonPoint> points = new List <PolygonPoint>(); List <Vector2> interpolatedPoints = new List <Vector2>(); float edgeCutLength = (chunkWidth + chunkHeight) * 0.5f; int triangleIndex = 0; int numChunksX; int numChunksY; outputPoints = new List <Vector2>(); outputIndices = new List <int>(); // Cut all the edges into smaller segments (so triangulation won't create long, thin shards along the edges) for (int i = 0; i < inputPoints.Count; i++) { Vector2 a; Vector2 b; float distance; int numCuts; float cutLength; a = i == 0 ? inputPoints[inputPoints.Count - 1] : inputPoints[i - 1]; b = inputPoints[i]; distance = (b - a).magnitude; numCuts = (int)(distance / edgeCutLength); cutLength = distance / (float)numCuts; for (int j = 0; j < numCuts; j++) { Vector2 p = Vector2.Lerp(a, b, Mathf.Max(0f, Mathf.Min(1f, (j * cutLength / distance)))); interpolatedPoints.Add(p); } } // Convert points to P2T, and create polygon foreach (Vector2 p in interpolatedPoints) { points.Add(new PolygonPoint(p.x, p.y)); } poly = new Polygon(points); // Calculate number of chunks to split the polygon up into numChunksX = (int)(poly.Bounds.Width / chunkWidth); numChunksY = (int)(poly.Bounds.Height / chunkHeight); // Add steiner points (this is the reason for using Poly2Tri) UnityEngine.Random.seed = (int)(poly.Bounds.Left * poly.Bounds.Top); for (int i = 0; i < numChunksX; i++) { for (int j = 0; j < numChunksY; j++) { TriangulationPoint p = new TriangulationPoint( i * chunkWidth + poly.Bounds.Left + UnityEngine.Random.Range(-jitterX, jitterX), j * -chunkHeight + poly.Bounds.Top + UnityEngine.Random.Range(-jitterY, jitterY)); if (poly.IsPointInside(p)) { poly.AddSteinerPoint(p); } } } // Triangulate P2T.Triangulate(poly); // Build output from triangulated polygon foreach (DelaunayTriangle triangle in poly.Triangles) { TriangulationPoint p1 = triangle.Points[0]; TriangulationPoint p2 = triangle.PointCWFrom(p1); TriangulationPoint p3 = triangle.PointCWFrom(p2); outputPoints.Add(new Vector2(p1.Xf, p1.Yf)); outputPoints.Add(new Vector2(p2.Xf, p2.Yf)); outputPoints.Add(new Vector2(p3.Xf, p3.Yf)); outputIndices.Add(triangleIndex++); outputIndices.Add(triangleIndex++); outputIndices.Add(triangleIndex++); } }