private void AddEdge(int v0, int v1, float cost) { // remove all edges crossing our clipping edge (TODO: could we split them instead?) Edge clippingEdge = new Edge(v0, v1, cost); Stack <Edge> candidates = new Stack <Edge>(); candidates.Push(clippingEdge); while (candidates.Count > 0) { Edge cEdge = candidates.Pop(); bool isect = false; if ((vertices[cEdge.v[0]] - vertices[cEdge.v[1]]).Length() > 1e-3f) { foreach (Edge e in edges) { Vertex p; if (e.v[0] != cEdge.v[0] && e.v[0] != cEdge.v[1] && e.v[1] != cEdge.v[0] && e.v[1] != cEdge.v[1] && GeomUtils.SegmentIntersect(vertices[e.v[0]], vertices[e.v[1]], vertices[cEdge.v[0]], vertices[cEdge.v[1]], out p)) { vertices.Add(p); int isectIdx = vertices.Count - 1; edges.Remove(e); edges.Add(new Edge(e.v[0], isectIdx, e.cost)); edges.Add(new Edge(isectIdx, e.v[1], e.cost)); candidates.Push(new Edge(cEdge.v[0], isectIdx, cost)); candidates.Push(new Edge(isectIdx, cEdge.v[1], cost)); isect = true; break; } } if (!isect) { edges.Add(cEdge); } } } }
public bool FlipTriangles(int tri1, int tri2, out int[] result) { Triangle triangle1 = triangles[tri1]; Debug.Assert(triangle1.valid); Triangle triangle2 = triangles[tri2]; Debug.Assert(triangle2.valid); int commonEdgeIdx = CommonEdge(triangle1, triangle2); Debug.Assert(commonEdgeIdx >= 0); Edge commonEdge = edges[commonEdgeIdx]; Debug.Assert(commonEdge.triangles[0] == tri1 || commonEdge.triangles[0] == tri2); Debug.Assert(commonEdge.triangles[1] == tri1 || commonEdge.triangles[1] == tri2); // Tri1 = A,B,C // Tri2 = B,D,C // commonEdge = B,C int localEdgeT1 = triangle1.LocalEdgeIndex(commonEdgeIdx); Debug.Assert(localEdgeT1 >= 0); int localEdgeT2 = triangle2.LocalEdgeIndex(commonEdgeIdx); Debug.Assert(localEdgeT2 >= 0); int A = VertexOutOfTriEdge(tri1, localEdgeT1); int D = VertexOutOfTriEdge(tri2, localEdgeT2); Debug.Assert(A >= 0); Debug.Assert(D >= 0); int B = (commonEdge.triangles[0] == tri1 ? commonEdge.vertices[0] : commonEdge.vertices[1]); int C = (B == commonEdge.vertices[0] ? commonEdge.vertices[1] : commonEdge.vertices[0]); Debug.Assert(A != B && A != C && A != D && B != C && B != D && C != D); result = new int[2]; if (!GeomUtils.SegmentIntersect(vertices[A], vertices[D], vertices[B], vertices[C])) { // can't flip result[0] = result[1] = -1; return(false); } float closestAngleBefore = Math.Min(ClosestAngleOnTri(A, B, C), ClosestAngleOnTri(B, D, C)); if (!IsWorthFlipping(A, B, C, D)) { // The resulting triangles would not improve the triangulation, don't bother return(false); } RemoveTriangle(tri1); RemoveTriangle(tri2); result[0] = CreateTriangle(A, B, D); result[1] = CreateTriangle(A, D, C); float closestAngleAfter = Math.Min(ClosestAngleOnTri(A, B, D), ClosestAngleOnTri(A, D, C)); //Debug.Assert(closestAngleBefore < closestAngleAfter); #if DEBUG Debug.Assert(CheckConsistency()); #endif return(true); }