/// <summary> /// Test the triad against its 3 neighbours and flip it with any neighbour whose opposite point /// is inside the circumcircle of the triad /// </summary> /// <param name="triads">The triads</param> /// <param name="triadIndexToTest">The index of the triad to test</param> /// <param name="triadIndexFlipped">Index of adjacent triangle it was flipped with (if any)</param> /// <returns>true iff the triad was flipped with any of its neighbours</returns> bool FlipTriangle(List <Triad> triads, int triadIndexToTest, out int triadIndexFlipped) { int oppositeVertex = 0, edge1, edge2, edge3 = 0, edge4 = 0; triadIndexFlipped = 0; Triad tri = triads[triadIndexToTest]; // test all 3 neighbours of tri if (tri.bc >= 0) { triadIndexFlipped = tri.bc; Triad t2 = triads[triadIndexFlipped]; // find relative orientation (shared limb). t2.FindAdjacency(tri.b, triadIndexToTest, out oppositeVertex, out edge3, out edge4); if (tri.InsideCircumcircle(points[oppositeVertex])) { // not valid in the Delaunay sense. edge1 = tri.ab; edge2 = tri.ac; if (edge1 != edge3 && edge2 != edge4) { int tria = tri.a, trib = tri.b, tric = tri.c; tri.Initialize(tria, trib, oppositeVertex, edge1, edge3, triadIndexFlipped, points); t2.Initialize(tria, tric, oppositeVertex, edge2, edge4, triadIndexToTest, points); // change knock on triangle labels. if (edge3 >= 0) { triads[edge3].ChangeAdjacentIndex(triadIndexFlipped, triadIndexToTest); } if (edge2 >= 0) { triads[edge2].ChangeAdjacentIndex(triadIndexToTest, triadIndexFlipped); } return(true); } } } if (tri.ab >= 0) { triadIndexFlipped = tri.ab; Triad t2 = triads[triadIndexFlipped]; // find relative orientation (shared limb). t2.FindAdjacency(tri.a, triadIndexToTest, out oppositeVertex, out edge3, out edge4); if (tri.InsideCircumcircle(points[oppositeVertex])) { // not valid in the Delaunay sense. edge1 = tri.ac; edge2 = tri.bc; if (edge1 != edge3 && edge2 != edge4) { int tria = tri.a, trib = tri.b, tric = tri.c; tri.Initialize(tric, tria, oppositeVertex, edge1, edge3, triadIndexFlipped, points); t2.Initialize(tric, trib, oppositeVertex, edge2, edge4, triadIndexToTest, points); // change knock on triangle labels. if (edge3 >= 0) { triads[edge3].ChangeAdjacentIndex(triadIndexFlipped, triadIndexToTest); } if (edge2 >= 0) { triads[edge2].ChangeAdjacentIndex(triadIndexToTest, triadIndexFlipped); } return(true); } } } if (tri.ac >= 0) { triadIndexFlipped = tri.ac; Triad t2 = triads[triadIndexFlipped]; // find relative orientation (shared limb). t2.FindAdjacency(tri.a, triadIndexToTest, out oppositeVertex, out edge3, out edge4); if (tri.InsideCircumcircle(points[oppositeVertex])) { // not valid in the Delaunay sense. edge1 = tri.ab; // .ac shared limb edge2 = tri.bc; if (edge1 != edge3 && edge2 != edge4) { int tria = tri.a, trib = tri.b, tric = tri.c; tri.Initialize(trib, tria, oppositeVertex, edge1, edge3, triadIndexFlipped, points); t2.Initialize(trib, tric, oppositeVertex, edge2, edge4, triadIndexToTest, points); // change knock on triangle labels. if (edge3 >= 0) { triads[edge3].ChangeAdjacentIndex(triadIndexFlipped, triadIndexToTest); } if (edge2 >= 0) { triads[edge2].ChangeAdjacentIndex(triadIndexToTest, triadIndexFlipped); } return(true); } } } return(false); }