linkResultDirectedEdges method
void
linkResultDirectedEdges()
Traverse the star of DirectedEdges, linking the included edges together.
To link two dirEdges, the next
pointer for an incoming dirEdge
is set to the next outgoing edge.
DirEdges are only linked if:
- they belong to an area (i.e. they have sides)
- they are marked as being in the result
Edges are linked in CCW order (the order they are stored). This means that rings have their face on the Right (in other words, the topological location of the face is given by the RHS label of the DirectedEdge)
PRECONDITION: No pair of dirEdges are both marked as being in the result
Implementation
void linkResultDirectedEdges() {
// make sure edges are copied to resultAreaEdges list
getResultAreaEdges();
// find first area edge (if any) to start linking at
DirectedEdge? firstOut = null;
DirectedEdge? incoming = null;
int state = SCANNING_FOR_INCOMING;
// link edges in CCW order
for (int i = 0; i < resultAreaEdgeList!.length; i++) {
DirectedEdge nextOut = resultAreaEdgeList![i] as DirectedEdge;
DirectedEdge nextIn = nextOut.getSym();
// skip de's that we're not interested in
if (!nextOut.getLabel()!.isArea()) continue;
// record first outgoing edge, in order to link the last incoming edge
if (firstOut == null && nextOut.isInResult()) firstOut = nextOut;
// assert: sym.isInResult() == false, since pairs of dirEdges should have been removed already
switch (state) {
case SCANNING_FOR_INCOMING:
if (!nextIn.isInResult()) continue;
incoming = nextIn;
state = LINKING_TO_OUTGOING;
break;
case LINKING_TO_OUTGOING:
if (!nextOut.isInResult()) continue;
incoming!.setNext(nextOut);
state = SCANNING_FOR_INCOMING;
break;
}
}
//Debug.print(this);
if (state == LINKING_TO_OUTGOING) {
//Debug.print(firstOut == null, this);
if (firstOut == null)
throw new TopologyException(
"no outgoing dirEdge found ${getCoordinate()}");
//Assert.isTrue(firstOut != null, "no outgoing dirEdge found (at " + getCoordinate() );
assert(firstOut.isInResult(), "unable to link last incoming dirEdge");
incoming!.setNext(firstOut);
}
}