TriangleNet.Mesh.SegmentIntersection C# (CSharp) Method

SegmentIntersection() private method

Find the intersection of an existing segment and a segment that is being inserted. Insert a vertex at the intersection, splitting an existing subsegment.
The segment being inserted connects the apex of splittri to endpoint2. splitsubseg is the subsegment being split, and MUST adjoin splittri. Hence, endpoints of the subsegment being split are the origin and destination of splittri. On completion, splittri is a handle having the newly inserted intersection point as its origin, and endpoint1 as its destination.
private SegmentIntersection ( TriangleNet.Data.Otri &splittri, TriangleNet.Data.Osub &splitsubseg, Vertex endpoint2 ) : void
splittri TriangleNet.Data.Otri
splitsubseg TriangleNet.Data.Osub
endpoint2 Vertex
return void
        private void SegmentIntersection(ref Otri splittri, ref Osub splitsubseg, Vertex endpoint2)
        {
            Osub opposubseg = default(Osub);
            Vertex endpoint1;
            Vertex torg, tdest;
            Vertex leftvertex, rightvertex;
            Vertex newvertex;
            InsertVertexResult success;

            double ex, ey;
            double tx, ty;
            double etx, ety;
            double split, denom;

            // Find the other three segment endpoints.
            endpoint1 = splittri.Apex();
            torg = splittri.Org();
            tdest = splittri.Dest();
            // Segment intersection formulae; see the Antonio reference.
            tx = tdest.x - torg.x;
            ty = tdest.y - torg.y;
            ex = endpoint2.x - endpoint1.x;
            ey = endpoint2.y - endpoint1.y;
            etx = torg.x - endpoint2.x;
            ety = torg.y - endpoint2.y;
            denom = ty * ex - tx * ey;
            if (denom == 0.0)
            {
                logger.Error("Attempt to find intersection of parallel segments.",
                    "Mesh.SegmentIntersection()");
                throw new Exception("Attempt to find intersection of parallel segments.");
            }
            split = (ey * etx - ex * ety) / denom;

            // Create the new vertex.
            newvertex = new Vertex(
                torg.x + split * (tdest.x - torg.x),
                torg.y + split * (tdest.y - torg.y),
                splitsubseg.seg.boundary,
                this.nextras);

            newvertex.hash = this.hash_vtx++;
            newvertex.id = newvertex.hash;

            // Interpolate its attributes.
            for (int i = 0; i < nextras; i++)
            {
                newvertex.attributes[i] = torg.attributes[i] + split * (tdest.attributes[i] - torg.attributes[i]);
            }

            vertices.Add(newvertex.hash, newvertex);

            // Insert the intersection vertex.  This should always succeed.
            success = InsertVertex(newvertex, ref splittri, ref splitsubseg, false, false);
            if (success != InsertVertexResult.Successful)
            {
                logger.Error("Failure to split a segment.", "Mesh.SegmentIntersection()");
                throw new Exception("Failure to split a segment.");
            }
            // Record a triangle whose origin is the new vertex.
            newvertex.tri = splittri;
            if (steinerleft > 0)
            {
                steinerleft--;
            }

            // Divide the segment into two, and correct the segment endpoints.
            splitsubseg.SymSelf();
            splitsubseg.Pivot(ref opposubseg);
            splitsubseg.Dissolve();
            opposubseg.Dissolve();
            do
            {
                splitsubseg.SetSegOrg(newvertex);
                splitsubseg.NextSelf();
            } while (splitsubseg.seg != Mesh.dummysub);
            do
            {
                opposubseg.SetSegOrg(newvertex);
                opposubseg.NextSelf();
            } while (opposubseg.seg != Mesh.dummysub);

            // Inserting the vertex may have caused edge flips.  We wish to rediscover
            // the edge connecting endpoint1 to the new intersection vertex.
            FindDirection(ref splittri, endpoint1);

            rightvertex = splittri.Dest();
            leftvertex = splittri.Apex();
            if ((leftvertex.x == endpoint1.x) && (leftvertex.y == endpoint1.y))
            {
                splittri.OnextSelf();
            }
            else if ((rightvertex.x != endpoint1.x) || (rightvertex.y != endpoint1.y))
            {
                logger.Error("Topological inconsistency after splitting a segment.", "Mesh.SegmentIntersection()");
                throw new Exception("Topological inconsistency after splitting a segment.");
            }
            // 'splittri' should have destination endpoint1.
        }