/// <summary> /// Returns all Edges that connect the two nodes (which are assumed to be different). /// </summary> /// <param name="node0"></param> /// <param name="node1"></param> /// <returns></returns> public static IList<DirectedEdge> GetEdgesBetween(Node node0, Node node1) { IList<Edge> edges0 = DirectedEdge.ToEdges(node0.OutEdges.Edges); var commonEdges = new Set<DirectedEdge>(Utilities.Caster.Cast<DirectedEdge>(edges0)); IList<Edge> edges1 = DirectedEdge.ToEdges(node1.OutEdges.Edges); commonEdges.RemoveMany(Utilities.Caster.Cast<DirectedEdge>(edges1)); return new List<DirectedEdge>(commonEdges); }
/// <summary> /// Deletes all edges at a node. /// </summary> /// <param name="node"></param> public static void DeleteAllEdges(Node node) { IList<DirectedEdge> edges = node.OutEdges.Edges; foreach (PolygonizeDirectedEdge de in edges) { de.Marked = true; PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge) de.Sym; if (sym != null) sym.Marked = true; } }
/// <summary> /// /// </summary> /// <param name="coordinate"></param> /// <returns></returns> private Node GetNode(Coordinate coordinate) { Node node = FindNode(coordinate); if (node == null) { node = new Node(coordinate); Add(node); } return node; }
/// <summary> /// /// </summary> /// <param name="node"></param> /// <param name="label"></param> /// <returns></returns> private static int GetDegree(Node node, long label) { IList<DirectedEdge> edges = node.OutEdges.Edges; int degree = 0; foreach (PolygonizeDirectedEdge de in edges) { if (de.Label == label) degree++; } return degree; }
/// <summary> /// /// </summary> /// <param name="node"></param> /// <returns></returns> private static int GetDegreeNonDeleted(Node node) { IList<DirectedEdge> edges = node.OutEdges.Edges; int degree = 0; foreach (PolygonizeDirectedEdge de in edges) { if (! de.IsMarked) degree++; } return degree; }
/// <summary> /// Constructs a LineMergeDirectedEdge connecting the <c>from</c> node to the <c>to</c> node. /// </summary> /// <param name="from"/> /// <param name="to"/> /// <param name="directionPt"> /// specifies this DirectedEdge's direction (given by an imaginary /// line from the <c>from</c> node to <c>directionPt</c>). /// </param> /// <param name="edgeDirection"> /// whether this DirectedEdge's direction is the same as or /// opposite to that of the parent Edge (if any). /// </param> public LineMergeDirectedEdge(Node from, Node to, Coordinate directionPt, bool edgeDirection) : base(from, to, directionPt, edgeDirection) { }
/// <summary> /// Computes the next edge pointers going CCW around the given node, for the /// given edgering label. /// This algorithm has the effect of converting maximal edgerings into minimal edgerings /// </summary> /// <param name="node"></param> /// <param name="label"></param> private static void ComputeNextCCWEdges(Node node, long label) { DirectedEdgeStar deStar = node.OutEdges; //PolyDirectedEdge lastInDE = null; PolygonizeDirectedEdge firstOutDE = null; PolygonizeDirectedEdge prevInDE = null; // the edges are stored in CCW order around the star IList<DirectedEdge> edges = deStar.Edges; //for (IEnumerator i = deStar.Edges.GetEnumerator(); i.MoveNext(); ) { for (int i = edges.Count - 1; i >= 0; i--) { PolygonizeDirectedEdge de = (PolygonizeDirectedEdge) edges[i]; PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge) de.Sym; PolygonizeDirectedEdge outDE = null; if (de.Label == label) outDE = de; PolygonizeDirectedEdge inDE = null; if (sym.Label == label) inDE = sym; if (outDE == null && inDE == null) continue; // this edge is not in edgering if (inDE != null) prevInDE = inDE; if (outDE != null) { if (prevInDE != null) { prevInDE.Next = outDE; prevInDE = null; } if (firstOutDE == null) firstOutDE = outDE; } } if (prevInDE != null) { Assert.IsTrue(firstOutDE != null); prevInDE.Next = firstOutDE; } }
/// <summary> /// /// </summary> /// <param name="node"></param> private static void ComputeNextCWEdges(Node node) { DirectedEdgeStar deStar = node.OutEdges; PolygonizeDirectedEdge startDE = null; PolygonizeDirectedEdge prevDE = null; // the edges are stored in CCW order around the star foreach (PolygonizeDirectedEdge outDE in deStar.Edges) { if (outDE.IsMarked) continue; if (startDE == null) startDE = outDE; if (prevDE != null) { PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge) prevDE.Sym; sym.Next = outDE; } prevDE = outDE; } if (prevDE != null) { PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge) prevDE.Sym; sym.Next = startDE; } }
/// <summary> /// /// </summary> /// <param name="pt"></param> /// <returns></returns> private Node GetNode(Coordinate pt) { Node node = FindNode(pt); if (node == null) { node = new Node(pt); // ensure node is only added once to graph Add(node); } return node; }
/// <summary> /// Finds an <see cref="DirectedEdge" /> for an unvisited edge (if any), /// choosing the <see cref="DirectedEdge" /> which preserves orientation, if possible. /// </summary> /// <param name="node">The <see cref="Node" /> to examine.</param> /// <returns> /// The <see cref="DirectedEdge" /> found, /// or <c>null</c> if none were unvisited. /// </returns> private static DirectedEdge FindUnvisitedBestOrientedDE(Node node) { DirectedEdge wellOrientedDE = null; DirectedEdge unvisitedDE = null; foreach(object obj in node.OutEdges) { DirectedEdge de = (DirectedEdge) obj; if (!de.Edge.IsVisited) { unvisitedDE = de; if (de.EdgeDirection) wellOrientedDE = de; } } if (wellOrientedDE != null) return wellOrientedDE; return unvisitedDE; }
/* /// <summary> /// Constructs a NodeMap without any Nodes. /// </summary> public NodeMap() { } */ /// <summary> /// Adds a node to the map, replacing any that is already at that location. /// </summary> /// <param name="n"></param> /// <returns>The added node.</returns> public Node Add(Node n) { _nodeMap[n.Coordinate] = n; return n; }
/// <summary> /// Adds a node to the map, replacing any that is already at that location. /// Only subclasses can add Nodes, to ensure Nodes are of the right type. /// </summary> /// <param name="node"></param> /// <returns>The added node.</returns> protected void Add(Node node) { nodeMap.Add(node); }
/// <summary> /// Removes a node from the graph, along with any associated DirectedEdges and /// Edges. /// </summary> /// <param name="node"></param> public void Remove(Node node) { // unhook all directed edges IList<DirectedEdge> outEdges = node.OutEdges.Edges; foreach (DirectedEdge de in outEdges) { DirectedEdge sym = de.Sym; // remove the diredge that points to this node if (sym != null) Remove(sym); // remove this diredge from the graph collection dirEdges.Remove(de); Edge edge = de.Edge; if (edge != null) _edges.Remove(edge); } // remove the node from the graph nodeMap.Remove(node.Coordinate); node.Remove(); }
/// <summary> /// Constructs a directed edge connecting the <c>from</c> node to the /// <c>to</c> node. /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <param name="directionPt"> /// Specifies this DirectedEdge's direction (given by an imaginary /// line from the <c>from</c> node to <c>directionPt</c>). /// </param> /// <param name="edgeDirection"> /// Whether this DirectedEdge's direction is the same as or /// opposite to that of the parent Edge (if any). /// </param> public PolygonizeDirectedEdge(Node from, Node to, Coordinate directionPt, bool edgeDirection) : base(from, to, directionPt, edgeDirection) { }
/// <summary> /// /// </summary> /// <param name="node"></param> private void BuildEdgeStringsStartingAt(Node node) { foreach (LineMergeDirectedEdge directedEdge in node.OutEdges) { if (directedEdge.Edge.IsMarked) continue; _edgeStrings.Add(BuildEdgeStringStartingWith(directedEdge)); } }