// Return a list of triangles with the vertices public static List <MeshPolygon> Triangulate(Polygon polygon) { List <MeshPolygon> triangles = new List <MeshPolygon>(); MeshPolygon triangle; int earIndex = 0; polygon.ReverseWindingOrder(); // No ears if (polygon.GetVerticesCount() < 3) { return(triangles); } // Set the values for the vertices for (int i = 0; i < polygon.GetVerticesCount(); i++) { UpdateVertex(i, polygon); } // Start clipping the ears while (polygon.GetVerticesCount() > 3) { var earFound = false; // find the most extruded ear for (int j = 0; j < polygon.GetVerticesCount(); j++) { if (!polygon.GetVertex(j).isEar) { continue; } if (!earFound) { earFound = true; earIndex = j; } else { float vAngle = GeometryHelper.GetAngle(polygon.GetPoint(j - 1), polygon.GetPoint(j), polygon.GetPoint(j + 1)); float earAngle = GeometryHelper.GetAngle(polygon.GetPoint(earIndex - 1), polygon.GetPoint(earIndex), polygon.GetPoint(earIndex + 1)); if (vAngle > earAngle) { earIndex = j; } } } if (!earFound) { return(triangles); } triangle = new MeshPolygon(); triangle.AddPoint(polygon.GetPoint(earIndex - 1)); triangle.AddPoint(polygon.GetPoint(earIndex)); triangle.AddPoint(polygon.GetPoint(earIndex + 1)); triangles.Add(triangle); // Clip the ear polygon.RemovePoint(earIndex); // Update the adjacent vertices UpdateVertex(earIndex - 1, polygon); UpdateVertex(earIndex, polygon); } // Add the last ear if (polygon.GetVerticesCount() == 3) { triangle = new MeshPolygon(); triangle.AddPoint(polygon.GetPoint(0)); triangle.AddPoint(polygon.GetPoint(1)); triangle.AddPoint(polygon.GetPoint(2)); triangles.Add(triangle); return(triangles); } return(triangles); }
// Remove the nonessential diagonals public static List <MeshPolygon> RemoveNonEssentialDiagonals(List <MeshPolygon> triangles) { MeshPolygon poly2 = null; int i21 = 0, i22 = 0; // Loop through the triangles int currentPoly = 0; while (currentPoly < triangles.Count) { var poly1 = triangles[currentPoly]; int i11; for (i11 = 0; i11 < poly1.GetVerticesCount(); i11++) { // Get the first line in the polygon var d1 = poly1.GetPoint(i11); var i12 = i11 + 1; var d2 = poly1.GetPoint(i12); // Find another polygon who shares this line var isDiagonal = false; for (int j1 = currentPoly; j1 < triangles.Count; j1++) { poly2 = triangles[j1]; if (poly1 == poly2) { continue; } // Find a common line with the next polygon to determine if it is a diagonal for (i21 = 0; i21 < poly2.GetVerticesCount(); i21++) { if ((d2.x != poly2.GetPoint(i21).x) || (d2.y != poly2.GetPoint(i21).y)) { continue; } i22 = i21 + 1; if ((d1.x != poly2.GetPoint(i22).x) || (d1.y != poly2.GetPoint(i22).y)) { continue; } // The line is found in an adjacent polygon isDiagonal = true; break; } if (isDiagonal) { break; } } // If no diagonal has been found between the current polygon and all the others then move to the next if (!isDiagonal) { continue; } // First point of the diagonal var p2 = poly1.GetPoint(i11); // Get the previous vertex var i13 = i11 - 1; var p1 = poly1.GetPoint(i13); // Get the next vertex on the other polygon var i23 = i22 + 1; var p3 = poly2.GetPoint(i23); // If the formed angle is reflex then the diagonal is essential if (GeometryHelper.IsReflex(p1, p2, p3)) { continue; } // Get vertex on the other end of the diagonal p2 = poly1.GetPoint(i12); // Get the next vertex on the first polygon i13 = i12 + 1; p3 = poly1.GetPoint(i13); // Get the previous vertex on the other polygon i23 = i21 - 1; p1 = poly2.GetPoint(i23); // If the formed angle is reflex then the diagonal is essential if (GeometryHelper.IsReflex(p1, p2, p3)) { continue; } var newPoly = new MeshPolygon(); int j; for (j = i12; j != i11; j = (j + 1) % (poly1.GetVerticesCount())) { newPoly.AddPoint(poly1.GetPoint(j)); } for (j = i22; j != i21; j = (j + 1) % (poly2.GetVerticesCount())) { newPoly.AddPoint(poly2.GetPoint(j)); } triangles.Remove(poly2); poly1 = newPoly; triangles[currentPoly] = poly1; i11 = -1; } currentPoly++; } return(triangles); }