public abstract void SetEdgeRing(DirectedEdge de, EdgeRing er);
public abstract DirectedEdge GetNext(DirectedEdge de);
/// <summary> /// Traverse the star of DirectedEdges, linking the included edges together. /// </summary> /// <remarks> /// <para> /// To link two DirectedEdges, the "next" pointer for an incoming DirectedEdge /// is set to the next outgoing edge. /// </para> /// DirectedEdges are only linked if: /// <list type="number"> /// <item> /// <description> /// they belong to an area (i.e. they have sides) /// </description> /// </item> /// <item> /// <description> /// they are marked as being in the result /// </description> /// </item> /// </list> /// <para> /// 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 right hand side label of the DirectedEdge) /// </para> /// PRECONDITION: No pair of DirectedEdges are both marked as being in the result. /// </remarks> public void LinkResultDirectedEdges() { // make sure edges are copied to resultAreaEdges list IList generatedAux = this.GetResultAreaEdges(); if (generatedAux == null) { return; } // 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.Count; i++) { DirectedEdge nextOut = (DirectedEdge)resultAreaEdgeList[i]; DirectedEdge nextIn = nextOut.Sym; // skip de's that we're not interested in if (!nextOut.Label.IsArea()) { continue; } // record first outgoing edge, in order to link the last incoming edge if (firstOut == null && nextOut.InResult) { firstOut = nextOut; } switch (state) { case SCANNING_FOR_INCOMING: if (!nextIn.InResult) { continue; } incoming = nextIn; state = LINKING_TO_OUTGOING; break; case LINKING_TO_OUTGOING: if (!nextOut.InResult) { continue; } incoming.Next = nextOut; state = SCANNING_FOR_INCOMING; break; } } if (state == LINKING_TO_OUTGOING) { if (firstOut == null) { throw new GeometryException("no outgoing dirEdge found", Coordinate); } Debug.Assert(firstOut.InResult, "unable to link last incoming dirEdge"); incoming.Next = firstOut; } }
/// <summary> /// Traverse the star of edges, maintaing the current location in the result /// area at this node (if any). /// If any L edges are found in the interior of the result, mark them as covered. /// </summary> public void FindCoveredLineEdges() { // Since edges are stored in CCW order around the node, // as we move around the ring we move from the right to the left side of the edge // Find first DirectedEdge of result area (if any). // The interior of the result is on the RHS of the edge, // so the start location will be: // - INTERIOR if the edge is outgoing // - EXTERIOR if the edge is incoming int startLoc = LocationType.None; for (IEnumerator it = Iterator(); it.MoveNext();) { DirectedEdge nextOut = (DirectedEdge)it.Current; DirectedEdge nextIn = nextOut.Sym; if (!nextOut.LineEdge) { if (nextOut.InResult) { startLoc = LocationType.Interior; break; } if (nextIn.InResult) { startLoc = LocationType.Exterior; break; } } } // no A edges found, so can't determine if L edges are covered or not if (startLoc == LocationType.None) { return; } // move around ring, keeping track of the current location // (Interior or Exterior) for the result area. // If L edges are found, mark them as covered if they are in the interior int currLoc = startLoc; for (IEnumerator it = Iterator(); it.MoveNext();) { DirectedEdge nextOut = (DirectedEdge)it.Current; DirectedEdge nextIn = nextOut.Sym; if (nextOut.LineEdge) { nextOut.Edge.Covered = currLoc == LocationType.Interior; } else { // edge is an Area edge if (nextOut.InResult) { currLoc = LocationType.Exterior; } if (nextIn.InResult) { currLoc = LocationType.Interior; } } } }
/// <summary> Insert a directed edge in the list</summary> public override void Insert(EdgeEnd ee) { DirectedEdge de = (DirectedEdge)ee; InsertEdgeEnd(de, de); }