/// <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 getEdgesBetween(Node node0, Node node1) { IList edges0 = DirectedEdge.ToEdges(node0.OutEdges.Edges); ISet commonEdges = new HashedSet(edges0); IList edges1 = DirectedEdge.ToEdges(node1.OutEdges.Edges); commonEdges.RetainAll(edges1); return new ArrayList(commonEdges); }
/// <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 getEdgesBetween(Node node0, Node node1) { IList edges0 = DirectedEdge.ToEdges(node0.OutEdges.Edges); Set<DirectedEdge> commonEdges = new Set<DirectedEdge>(edges0.Cast<DirectedEdge>()); IList edges1 = DirectedEdge.ToEdges(node1.OutEdges.Edges); commonEdges.RemoveMany(edges1.Cast<DirectedEdge>()); return new ArrayList(commonEdges); }
/// <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) { ICoordinate key = n.Coordinate; bool contains = nodeMap.Contains(key); if (!contains) nodeMap.Add(key, n); return n; }
/// <summary> /// /// </summary> /// <param name="coordinate"></param> /// <returns></returns> private Node GetNode(ICoordinate coordinate) { Node node = FindNode(coordinate); if (node == null) { node = new Node(coordinate); Add(node); } return node; }
/// <summary> /// Adds all nodes and edges reachable from this node to the subgraph. /// Uses an explicit stack to avoid a large depth of recursion. /// </summary> /// <param name="startNode"></param> /// <param name="subgraph"></param> private void AddReachable(Node startNode, Subgraph subgraph) { Stack nodeStack = new Stack(); nodeStack.Push(startNode); while (!(nodeStack.Count == 0)) { Node node = (Node)nodeStack.Pop(); AddEdges(node, nodeStack, subgraph); } }
/// <summary> /// Returns the DirectedEdge that starts from the given node, or null if the /// node is not one of the two nodes associated with this Edge. /// </summary> /// <param name="fromNode"></param> /// <returns></returns> public DirectedEdge GetDirEdge(Node fromNode) { if (dirEdge[0].FromNode == fromNode) return dirEdge[0]; if (dirEdge[1].FromNode == fromNode) return dirEdge[1]; // node not found // possibly should throw an exception here? return null; }
/// <summary> /// Deletes all edges at a node. /// </summary> /// <param name="node"></param> public static void DeleteAllEdges(Node node) { IList edges = node.OutEdges.Edges; for (IEnumerator i = edges.GetEnumerator(); i.MoveNext(); ) { PolygonizeDirectedEdge de = (PolygonizeDirectedEdge) i.Current; de.Marked = true; PolygonizeDirectedEdge sym = (PolygonizeDirectedEdge) de.Sym; if (sym != null) sym.Marked = true; } }
/// <summary> /// /// </summary> /// <param name="node"></param> /// <returns></returns> private static int GetDegreeNonDeleted(Node node) { IList edges = node.OutEdges.Edges; int degree = 0; for (IEnumerator i = edges.GetEnumerator(); i.MoveNext(); ) { PolygonizeDirectedEdge de = (PolygonizeDirectedEdge) i.Current; if (! de.IsMarked) degree++; } return degree; }
/// <summary> /// /// </summary> /// <param name="node"></param> /// <param name="label"></param> /// <returns></returns> private static int GetDegree(Node node, long label) { IList edges = node.OutEdges.Edges; int degree = 0; for (IEnumerator i = edges.GetEnumerator(); i.MoveNext(); ) { PolygonizeDirectedEdge de = (PolygonizeDirectedEdge) i.Current; if (de.Label == label) degree++; } return degree; }
/// <summary> /// Adds the argument node and all its out edges to the subgraph. /// </summary> /// <param name="node"></param> /// <param name="nodeStack"></param> /// <param name="subgraph"></param> private void AddEdges(Node node, Stack nodeStack, Subgraph subgraph) { node.Visited = true; IEnumerator i = ((DirectedEdgeStar)node.OutEdges).GetEnumerator(); while(i.MoveNext()) { DirectedEdge de = (DirectedEdge)i.Current; subgraph.Add(de.Edge); Node toNode = de.ToNode; if (!toNode.IsVisited) nodeStack.Push(toNode); } }
/// <summary> /// Constructs a LineMergeDirectedEdge 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 LineMergeDirectedEdge(Node from, Node to, ICoordinate directionPt, bool edgeDirection) : base(from, to, directionPt, edgeDirection) { }
/// <summary> /// /// </summary> /// <param name="node"></param> private void BuildEdgeStringsStartingAt(Node node) { IEnumerator i = node.OutEdges.GetEnumerator(); while (i.MoveNext()) { LineMergeDirectedEdge directedEdge = (LineMergeDirectedEdge) i.Current; if (directedEdge.Edge.IsMarked) continue; edgeStrings.Add(BuildEdgeStringStartingWith(directedEdge)); } }
/// <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 outEdges = node.OutEdges.Edges; for (IEnumerator i = outEdges.GetEnumerator(); i.MoveNext(); ) { DirectedEdge de = (DirectedEdge) i.Current; 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> /// 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> /// If <c>node</c> is one of the two nodes associated with this Edge, /// returns the other node; otherwise returns null. /// </summary> /// <param name="node"></param> /// <returns></returns> public Node GetOppositeNode(Node node) { if (dirEdge[0].FromNode == node) return dirEdge[0].ToNode; if (dirEdge[1].FromNode == node) return dirEdge[1].ToNode; // node not found // possibly should throw an exception here? return null; }
/// <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 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; } }
private Subgraph FindSubgraph(Node node) { Subgraph subgraph = new Subgraph(graph); AddReachable(node, subgraph); return subgraph; }
/// <summary> /// /// </summary> /// <param name="pt"></param> /// <returns></returns> private Node GetNode(ICoordinate 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> /// 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, ICoordinate directionPt, bool edgeDirection) : base(from, to, directionPt, edgeDirection) { }
/// <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 for (IEnumerator i = deStar.Edges.GetEnumerator(); i.MoveNext(); ) { PolygonizeDirectedEdge outDE = (PolygonizeDirectedEdge) i.Current; 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> /// 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; }