TriangleNet.Mesh.DelaunayFixup C# (CSharp) Method

DelaunayFixup() private method

Enforce the Delaunay condition at an edge, fanning out recursively from an existing vertex. Pay special attention to stacking inverted triangles.
This is a support routine for inserting segments into a constrained Delaunay triangulation. The origin of fixuptri is treated as if it has just been inserted, and the local Delaunay condition needs to be enforced. It is only enforced in one sector, however, that being the angular range defined by fixuptri. This routine also needs to make decisions regarding the "stacking" of triangles. (Read the description of ConstrainedEdge() below before reading on here, so you understand the algorithm.) If the position of the new vertex (the origin of fixuptri) indicates that the vertex before it on the polygon is a reflex vertex, then "stack" the triangle by doing nothing. (fixuptri is an inverted triangle, which is how stacked triangles are identified.) Otherwise, check whether the vertex before that was a reflex vertex. If so, perform an edge flip, thereby eliminating an inverted triangle (popping it off the stack). The edge flip may result in the creation of a new inverted triangle, depending on whether or not the new vertex is visible to the vertex three edges behind on the polygon. If neither of the two vertices behind the new vertex are reflex vertices, fixuptri and fartri, the triangle opposite it, are not inverted; hence, ensure that the edge between them is locally Delaunay.
private DelaunayFixup ( TriangleNet.Data.Otri &fixuptri, bool leftside ) : void
fixuptri TriangleNet.Data.Otri
leftside bool Indicates whether or not fixuptri is to the left of /// the segment being inserted. (Imagine that the segment is pointing up from /// endpoint1 to endpoint2.)
return void
        private void DelaunayFixup(ref Otri fixuptri, bool leftside)
        {
            Otri neartri = default(Otri);
            Otri fartri = default(Otri);
            Osub faredge = default(Osub);
            Vertex nearvertex, leftvertex, rightvertex, farvertex;

            fixuptri.Lnext(ref neartri);
            neartri.Sym(ref fartri);
            // Check if the edge opposite the origin of fixuptri can be flipped.
            if (fartri.triangle == Mesh.dummytri)
            {
                return;
            }
            neartri.SegPivot(ref faredge);
            if (faredge.seg != Mesh.dummysub)
            {
                return;
            }
            // Find all the relevant vertices.
            nearvertex = neartri.Apex();
            leftvertex = neartri.Org();
            rightvertex = neartri.Dest();
            farvertex = fartri.Apex();
            // Check whether the previous polygon vertex is a reflex vertex.
            if (leftside)
            {
                if (Primitives.CounterClockwise(nearvertex, leftvertex, farvertex) <= 0.0)
                {
                    // leftvertex is a reflex vertex too. Nothing can
                    // be done until a convex section is found.
                    return;
                }
            }
            else
            {
                if (Primitives.CounterClockwise(farvertex, rightvertex, nearvertex) <= 0.0)
                {
                    // rightvertex is a reflex vertex too.  Nothing can
                    // be done until a convex section is found.
                    return;
                }
            }
            if (Primitives.CounterClockwise(rightvertex, leftvertex, farvertex) > 0.0)
            {
                // fartri is not an inverted triangle, and farvertex is not a reflex
                // vertex.  As there are no reflex vertices, fixuptri isn't an
                // inverted triangle, either.  Hence, test the edge between the
                // triangles to ensure it is locally Delaunay.
                if (Primitives.InCircle(leftvertex, farvertex, rightvertex, nearvertex) <= 0.0)
                {
                    return;
                }
                // Not locally Delaunay; go on to an edge flip.
            }
            // else fartri is inverted; remove it from the stack by flipping.
            Flip(ref neartri);
            fixuptri.LprevSelf();    // Restore the origin of fixuptri after the flip.
            // Recursively process the two triangles that result from the flip.
            DelaunayFixup(ref fixuptri, leftside);
            DelaunayFixup(ref fartri, leftside);
        }