///<summary> ///use to add the eight neighboring edges of a graph node that ///is positioned in a grid layout ///</summary> ///<param name="graph"></param> ///<param name="row"></param> ///<param name="col"></param> ///<param name="numCellsX"></param> ///<param name="numCellsY"></param> public static void AddAllNeighborsToGridNode( SparseGraph graph, int row, int col, int numCellsX, int numCellsY) { for (int i = -1; i < 2; ++i) { for (int j = -1; j < 2; ++j) { int nodeX = col + j; int nodeY = row + i; //skip if equal to this node if ((i == 0) && (j == 0)) continue; //check to see if this is a valid neighbor if (!ValidNeighbor(nodeX, nodeY, numCellsX, numCellsY)) continue; //calculate the distance to this node Vector2 posNode = graph.GetNode(row*numCellsX + col).Position; Vector2 posNeighbour = graph.GetNode(nodeY*numCellsX + nodeX).Position; float dist = (posNode - posNeighbour).Length(); //this neighbor is okay so it can be added NavGraphEdge newEdge = new NavGraphEdge( row*numCellsX + col, nodeY*numCellsX + nodeX, dist); graph.AddEdge(newEdge); //if graph is not a digraph, an edge needs to be added going //in the other direction if (graph.IsDigraph) continue; NavGraphEdge newReverseEdge = new NavGraphEdge( nodeY*numCellsX + nodeX, row*numCellsX + col, dist); graph.AddEdge(newReverseEdge); } } }
private bool Search() { //create a queue of edges Queue<NavGraphEdge> queue = new Queue<NavGraphEdge>(); //create a dummy edge and put on the queue NavGraphEdge dummy = new NavGraphEdge(Source, Source, 0); queue.Enqueue(dummy); //mark the source node as visited Visited[Source] = (int) SearchStatus.Visited; //while there are edges in the queue keep searching while (queue.Count > 0) { //grab the next edge NavGraphEdge next = queue.Peek(); //remove the edge from the queue queue.Dequeue(); //make a note of the parent of the node this edge points to Route[next.To] = next.From; //put it on the tree. //(making sure the dummy edge is not placed on the tree) if (next != dummy) { SpanningTree.Add(next); } //if the target has been found the method can return success if (next.To == Target) { return true; } //push the edges leading from the node at the end of this edge //onto the queue foreach (NavGraphEdge curEdge in Graph.Edges[next.To]) { if (Visited[curEdge.To] != (int) SearchStatus.Unvisited) continue; //if the node hasn't already been visited we can push //the edge onto the queue queue.Enqueue(curEdge); //and mark it visited Visited[curEdge.To] = (int) SearchStatus.Visited; } } //no path to target return false; }
///<summary> ///load graph from map data ///</summary> ///<param name="mapData"></param> ///<returns>true if successful</returns> public bool Load(MapData mapData) { Clear(); //get the number of nodes and read them in int numNodes = mapData.NodeList.Count; for (int n = 0; n < numNodes; ++n) { NavGraphNode newNode = new NavGraphNode(mapData.NodeList[n]); //when editing graphs (with Buckland's Raven map editor), it's //possible to end up with a situation where some of the nodes //have been invalidated (their id's set to invalid_node_index). //Therefore when a node of index invalid_node_index is //encountered, it must still be added. if (!GraphNode.IsInvalidIndex(newNode.Index)) { AddNode(newNode); } else { Nodes.Add(newNode); //make sure an edgelist is added for each node Edges.Add(new LinkedList<NavGraphEdge>()); ++NextNodeIndex; } } //now add the edges int numEdges = mapData.EdgeList.Count; for (int e = 0; e < numEdges; ++e) { NavGraphEdge nextEdge = new NavGraphEdge(mapData.EdgeList[e]); Edges[nextEdge.From].AddLast(nextEdge); } return true; }
///<summary> ///Use this to add an edge to the graph. The method will ensure that the ///edge passed as a parameter is valid before adding it to the graph. If ///the graph is a digraph then a similar edge connecting the nodes in ///the opposite direction will be automatically added. ///</summary> ///<param name="edge"></param> public void AddEdge(NavGraphEdge edge) { //first make sure the from and to nodes exist within the graph Assert.Fatal((edge.From < NextNodeIndex) && (edge.To < NextNodeIndex), "SparseGraph.AddEdge: invalid node index"); //make sure both nodes are active before adding the edge if (GraphNode.IsInvalidIndex(Nodes[edge.To].Index) || GraphNode.IsInvalidIndex(Nodes[edge.From].Index)) return; //add the edge, first making sure it is unique if (UniqueEdge(edge.From, edge.To)) { Edges[edge.From].AddLast(edge); } //if the graph is undirected we must add another connection //in the opposite direction if (IsDigraph) return; //check to make sure the edge is unique before adding if (!UniqueEdge(edge.To, edge.From)) return; NavGraphEdge newEdge = edge; newEdge.To = edge.From; newEdge.From = edge.To; Edges[edge.To].AddLast(newEdge); }
private bool Search() { //create a stack of edges Stack<NavGraphEdge> stack = new Stack<NavGraphEdge>(); //create a dummy edge and put on the stack NavGraphEdge dummy = new NavGraphEdge(Source, Source, 0); stack.Push(dummy); //while there are edges in the stack keep searching while (stack.Count > 0) { //grab the next edge NavGraphEdge next = stack.Peek(); //remove the edge from the stack stack.Pop(); //make a note of the parent of the node this edge points to Route[next.To] = next.From; //put it on the tree. //(making sure the dummy edge is not placed on the tree) if (next != dummy) { SpanningTree.Add(next); } //and mark it visited Visited[next.To] = (int) SearchStatus.Visited; //if the target has been found the method can return success if (next.To == Target) { return true; } //push the edges leading from the node this edge points to onto //the stack (provided the edge does not point to a previously //visited node) foreach (NavGraphEdge curEdge in Graph.Edges[next.To]) { if (Visited[curEdge.To] == (int) SearchStatus.Unvisited) { stack.Push(curEdge); } } } //no path to target return false; }