private SectorPolygon EarClip(List <Vector2> polygon) { SectorPolygon output = new SectorPolygon(); // Early out for convex polygons int conv = IsConvex(polygon); if (conv != 0) { if (conv == -1) { polygon.Reverse(); } output.points = polygon; for (int t = 0; t < polygon.Count - 2; t++) { output.triangles.Add(0); output.triangles.Add(t + 1); output.triangles.Add(t + 2); } return(output); } // Make it clockwise because consistent direction is necessary List <int> clippedIndexes = new List <int>(); int polygonCount = polygon.Count; int i = 0; int i1, i2, i3; int safe = 500; while (clippedIndexes.Count < polygonCount - 2 && safe >= 0) // be careful!!! { safe -= 1; i1 = i % polygonCount; while (clippedIndexes.Contains(i1)) { i1 = (i1 + 1) % polygonCount; } i2 = (i1 + 1) % polygonCount; while (clippedIndexes.Contains(i2) || i2 == i1) { i2 = (i2 + 1) % polygonCount; } i3 = (i2 + 1) % polygonCount; while (clippedIndexes.Contains(i3) || i3 == i2) { i3 = (i3 + 1) % polygonCount; } bool clipped = false; bool intersects = false; bool straightLine = false; if (polygon[i1].y == polygon[i2].y && polygon[i1].y == polygon[i3].y) { straightLine = true; } if (straightLine == false) { for (int j = 0; j < polygonCount; j++) { int j1 = (j + 1) % polygonCount; if (!Vector2.Equals(polygon[i1], polygon[j]) && !Vector2.Equals(polygon[i3], polygon[j]) && !Vector2.Equals(polygon[i1], polygon[j1]) && !Vector2.Equals(polygon[i3], polygon[j1]) && LinesIntersect(polygon, i1, i3, j, j1)) { intersects = true; break; } } } //Debug.Log(intersects); if (intersects == false && straightLine == false) { Vector2 midpoint = new Vector2((polygon[i3].x + polygon[i1].x) / 2f, (polygon[i3].y + polygon[i1].y) / 2f); if (PointInPolygon(midpoint, polygon)) { // Clippit!!! clippedIndexes.Add(i2); output.triangles.Add(i1); output.triangles.Add(i2); output.triangles.Add(i3); clipped = true; } } if (clipped == false) { i += 1; } } if (safe <= 0) { Debug.LogWarning("EarClip: while loop broke safety net. Clipped Indexes :" + clippedIndexes.Count + " polygonCount: " + polygonCount); } if (!IsClockwise(polygon)) { output.triangles.Reverse(); } output.points = polygon; return(output); }
public List <SectorPolygon> Triangulate(int sector, bool benchmark = false) { float time = 0f; if (benchmark) { time = Time.realtimeSinceStartup; } int i; // Trace sector lines List <List <Vector2> > polygons = TraceLines(sector); //Debug.Log("Polygons: " + polygons.Count); // Determine islands if (polygons.Count == 0) { return(null); } List <SectorIsland> islands = BuildIslands(polygons); // Cut islands List <List <Vector2> > cutPolygons = new List <List <Vector2> >(); for (i = 0; i < islands.Count; i++) { List <Vector2> cut = islands[i].Cut(); if (cut != null) { cutPolygons.Add(cut); } } // Ear clip List <SectorPolygon> output = new List <SectorPolygon>(); for (i = 0; i < cutPolygons.Count; i++) { SectorPolygon sp = EarClip(cutPolygons[i]); if (sp != null) { output.Add(EarClip(cutPolygons[i])); } } // for (i = 0; i < cutPolygons.Count; i++) { // int conv = IsConvex(cutPolygons[i]); // if (conv != 0) { // if (conv == -1) cutPolygons[i].Reverse(); // output.AddRange(cutPolygons[i]); // } // } // Output if (benchmark) { Debug.Log("Triangulation time: " + (Time.realtimeSinceStartup - time)); } return(output); }