//Alternative 1. Triangulate with some algorithm - then flip edges until we have a delaunay triangulation public static List <Triangle> TriangulateByFlippingEdges(List <Vector3> sites) { //Step 1. Triangulate the points with some algorithm //Vector3 to vertex List <Vertex> vertices = new List <Vertex>(); for (int i = 0; i < sites.Count; i++) { vertices.Add(new Vertex(sites[i])); } //Triangulate the convex hull of the sites List <Triangle> triangles = IncrementalTriangulationAlgorithm.TriangulatePoints(vertices); //List triangles = TriangulatePoints.TriangleSplitting(vertices); //Step 2. Change the structure from triangle to half-edge to make it faster to flip edges List <HalfEdge> halfEdges = Delaunay.TransformFromTriangleToHalfEdge(triangles); //Step 3. Flip edges until we have a delaunay triangulation int safety = 0; int flippedEdges = 0; while (true) { safety += 1; if (safety > 100000) { Debug.WriteLine("Stuck in endless loop"); break; } bool hasFlippedEdge = false; //Search through all edges to see if we can flip an edge for (int i = 0; i < halfEdges.Count; i++) { HalfEdge thisEdge = halfEdges[i]; //Is this edge sharing an edge, otherwise its a border, and then we cant flip the edge if (thisEdge.oppositeEdge == null) { continue; } //The vertices belonging to the two triangles, c-a are the edge vertices, b belongs to this triangle Vertex a = thisEdge.v; Vertex b = thisEdge.nextEdge.v; Vertex c = thisEdge.prevEdge.v; Vertex d = thisEdge.oppositeEdge.nextEdge.v; Vector2 aPos = a.GetPos2D_XZ(); Vector2 bPos = b.GetPos2D_XZ(); Vector2 cPos = c.GetPos2D_XZ(); Vector2 dPos = d.GetPos2D_XZ(); //Use the circle test to test if we need to flip this edge if (Delaunay.IsPointInsideOutsideOrOnCircle(aPos, bPos, cPos, dPos) < 0f) { //Are these the two triangles that share this edge forming a convex quadrilateral? //Otherwise the edge cant be flipped if (Delaunay.IsQuadrilateralConvex(aPos, bPos, cPos, dPos)) { //If the new triangle after a flip is not better, then dont flip //This will also stop the algoritm from ending up in an endless loop if (Delaunay.IsPointInsideOutsideOrOnCircle(bPos, cPos, dPos, aPos) < 0f) { continue; } //Flip the edge flippedEdges += 1; hasFlippedEdge = true; FlipEdge(thisEdge); } } } //We have searched through all edges and havent found an edge to flip, so we have a Delaunay triangulation! if (!hasFlippedEdge) { //Debug.Log("Found a delaunay triangulation"); break; } } //Debug.Log("Flipped edges: " + flippedEdges); //Dont have to convert from half edge to triangle because the algorithm will modify the objects, which belongs to the //original triangles, so the triangles have the data we need return(triangles); }