/// <summary> /// Insert. /// </summary> /// <param name="v"></param> /// <param name="old"></param> protected void Insert(Vertex v, Triangle old) { // Avoid duplicates, if this facet contains v as a vertex, // just return. if ((old.A.X == v.X) && (old.A.Y == v.Y)) { return; } if ((old.B.X == v.X) && (old.B.Y == v.Y)) { return; } if ((old.C.X == v.X) && (old.C.Y == v.Y)) { return; } m_points.Add(v); // Split old into 3 triangles, // Because old is counter clockwise, when duplicated, // ab, bc, ca is counter clockwise. // By changing one point and keeping to the commutation, // they remain counter clockwise. Triangle ab = new Triangle(old); // contains old ab, v is new C. Triangle bc = new Triangle(old); // contains old bc, v is new A. Triangle ca = new Triangle(old); // contains old ca, v is new B. ab.C = v; bc.A = v; ca.B = v; // This also makes assigning the sides easy. ab.BC = bc; ab.CA = ca; bc.AB = ab; bc.CA = ca; ca.AB = ab; ca.BC = bc; // The existing trianges that share an edge with old, // now share an edge with one of the three new triangles. // Repair the existing. // One way of looking at it: // for (int j = 0; j < 3; j++) // { // if ((ab.AB != null) && (ab.AB.Edge(j) == old)) ab.AB.SetEdge(j, ab); // if ((bc.BC != null) && (bc.BC.Edge(j) == old)) bc.BC.SetEdge(j, bc); // if ((ca.CA != null) && (ca.CA.Edge(j) == old)) ca.CA.SetEdge(j, ca); // } // This is faster, null check is once per edge, and default logic // reduces the compares by one. Instead of 3*3*2 comparisons = 18, // Worst case is 3*3 = 9, Average is 2+3+3=8. Triangle[] ta = { ab.AB, bc.BC, ca.CA }; Triangle[] tb = { ab, bc, ca }; for (int j = 0; j < 3; j++) { if (ta[j] == null) { continue; } if (ta[j].Edge(0) == old) { ta[j].SetEdge(0, tb[j]); continue; } if (ta[j].Edge(1) == old) { ta[j].SetEdge(1, tb[j]); continue; } ta[j].SetEdge(2, tb[j]); } // Add the new, remove the old. Facets.Add(ab); Facets.Add(bc); Facets.Add(ca); Facets.Remove(old); // Check for 1st order flipping. // Triangle ab has neighbor ab.AB. // Depth of up to recursion deep. // Remember that due to commutators, same.same is outward, // same.different is inward. flipIfNeeded(ab, ab.AB, Recursion); flipIfNeeded(bc, bc.BC, Recursion); flipIfNeeded(ca, ca.CA, Recursion); return; }