/// <summary> /// Create a new subsegment and inserts it between two triangles. Its /// vertices are properly initialized. /// </summary> /// <param name="tri">The new subsegment is inserted at the edge /// described by this handle.</param> /// <param name="subsegmark">The marker 'subsegmark' is applied to the /// subsegment and, if appropriate, its vertices.</param> internal void InsertSubseg(ref Otri tri, int subsegmark) { Otri oppotri = default(Otri); Osub newsubseg = default(Osub); Vertex triorg, tridest; triorg = tri.Org(); tridest = tri.Dest(); // Mark vertices if possible. if (triorg.mark == 0) { triorg.mark = subsegmark; } if (tridest.mark == 0) { tridest.mark = subsegmark; } // Check if there's already a subsegment here. tri.SegPivot(ref newsubseg); if (newsubseg.seg == dummysub) { // Make new subsegment and initialize its vertices. MakeSegment(ref newsubseg); newsubseg.SetOrg(tridest); newsubseg.SetDest(triorg); newsubseg.SetSegOrg(tridest); newsubseg.SetSegDest(triorg); // Bond new subsegment to the two triangles it is sandwiched between. // Note that the facing triangle 'oppotri' might be equal to 'dummytri' // (outer space), but the new subsegment is bonded to it all the same. tri.SegBond(ref newsubseg); tri.Sym(ref oppotri); newsubseg.SymSelf(); oppotri.SegBond(ref newsubseg); newsubseg.seg.boundary = subsegmark; } else { if (newsubseg.seg.boundary == 0) { newsubseg.seg.boundary = subsegmark; } } }
/// <summary> /// Delete a vertex from a Delaunay triangulation, ensuring that the /// triangulation remains Delaunay. /// </summary> /// <param name="deltri"></param> /// <remarks>The origin of 'deltri' is deleted. The union of the triangles /// adjacent to this vertex is a polygon, for which the Delaunay triangulation /// is found. Two triangles are removed from the mesh. /// /// Only interior vertices that do not lie on segments or boundaries /// may be deleted. /// </remarks> internal void DeleteVertex(ref Otri deltri) { Otri countingtri = default(Otri); Otri firstedge = default(Otri), lastedge = default(Otri); Otri deltriright = default(Otri); Otri lefttri = default(Otri), righttri = default(Otri); Otri leftcasing = default(Otri), rightcasing = default(Otri); Osub leftsubseg = default(Osub), rightsubseg = default(Osub); Vertex delvertex; Vertex neworg; int edgecount; delvertex = deltri.Org(); VertexDealloc(delvertex); // Count the degree of the vertex being deleted. deltri.Onext(ref countingtri); edgecount = 1; while (!deltri.Equal(countingtri)) { edgecount++; countingtri.OnextSelf(); } if (edgecount > 3) { // Triangulate the polygon defined by the union of all triangles // adjacent to the vertex being deleted. Check the quality of // the resulting triangles. deltri.Onext(ref firstedge); deltri.Oprev(ref lastedge); TriangulatePolygon(firstedge, lastedge, edgecount, false, behavior.NoBisect == 0); } // Splice out two triangles. deltri.Lprev(ref deltriright); deltri.Dnext(ref lefttri); lefttri.Sym(ref leftcasing); deltriright.Oprev(ref righttri); righttri.Sym(ref rightcasing); deltri.Bond(ref leftcasing); deltriright.Bond(ref rightcasing); lefttri.SegPivot(ref leftsubseg); if (leftsubseg.seg != Mesh.dummysub) { deltri.SegBond(ref leftsubseg); } righttri.SegPivot(ref rightsubseg); if (rightsubseg.seg != Mesh.dummysub) { deltriright.SegBond(ref rightsubseg); } // Set the new origin of 'deltri' and check its quality. neworg = lefttri.Org(); deltri.SetOrg(neworg); if (behavior.NoBisect == 0) { quality.TestTriangle(ref deltri); } // Delete the two spliced-out triangles. TriangleDealloc(lefttri.triangle); TriangleDealloc(righttri.triangle); }