Exemple #1
0
        public void Render(Graphics objGraphics)
        {
            //render all the cells
            for (int nd = 0; nd < m_Graph.NumNodes(); ++nd)
            {
                int left = (int)(m_Graph.GetNode(nd).Pos.X - m_dCellWidth / 2.0);
                int top = (int)(m_Graph.GetNode(nd).Pos.Y - m_dCellHeight / 2.0);
                int right = (int)(1 + m_Graph.GetNode(nd).Pos.X + m_dCellWidth / 2.0);
                int bottom = (int)(1 + m_Graph.GetNode(nd).Pos.Y + m_dCellHeight / 2.0);

                Rectangle rect = Rectangle.FromLTRB(left, top, right, bottom);

                SolidBrush fillBrush = new SolidBrush(Color.Gray);

                switch (m_TerrainType[nd])
                {
                    case (int)brush_type.normal:
                        fillBrush.Color = Color.White;
                        break;

                    case (int)brush_type.obstacle:
                        fillBrush.Color = Color.Black;
                        break;

                    case (int)brush_type.water:
                        fillBrush.Color = Color.DodgerBlue;
                        break;

                    case (int)brush_type.mud:
                        fillBrush.Color = Color.Brown;
                        break;

                    default:
                        fillBrush.Color = Color.White;
                        break;

                }//end switch

                objGraphics.FillRectangle(fillBrush, rect);

                if (m_bShowTiles)
                {
                    objGraphics.DrawLine(Pens.Gray, rect.Location, new Point(rect.Right, rect.Top));
                    objGraphics.DrawLine(Pens.Gray, rect.Location, new Point(rect.Left, rect.Bottom));
                }

                if (nd == m_iTargetCell)
                {
                    rect.Inflate(-4, -4);
                    objGraphics.FillRectangle(Brushes.Red, rect);
                    objGraphics.DrawString("T", m_font, Brushes.Black, rect.Right - (int)(rect.Width * 0.75), rect.Y); 
                }
                else if (nd == m_iSourceCell)
                {
                    rect.Inflate(-4, -4);
                    objGraphics.FillRectangle(Brushes.LightGreen, rect);
                    objGraphics.DrawString("S", m_font, Brushes.Black, rect.Right - (int)(rect.Width * 0.75), rect.Y); 
                }

                //render dots at the corners of the cells
                objGraphics.DrawLine(m_ThickBlack, left, top, left + 1, top + 1);
            }

            //draw the graph nodes and edges if rqd
            if (m_bShowGraph)
            {
                if (m_Graph.NumNodes() > 0)
                {
                    SparseGraph.NodeIterator NodeItr = new SparseGraph.NodeIterator(m_Graph);

                    while (NodeItr.MoveNext())
                    {
                        objGraphics.DrawEllipse(Pens.LightGray, (int)(NodeItr.Current.Pos.X - 2), (int)(NodeItr.Current.Pos.Y - 2), (int)2 * 2, (int)2 * 2);

                        SparseGraph.EdgeIterator EdgeItr = new SparseGraph.EdgeIterator(m_Graph, NodeItr.Current.Index);

                        while (EdgeItr.MoveNext())
                        {
                            objGraphics.DrawLine(Pens.LightGray, (int)NodeItr.Current.Pos.X, (int)NodeItr.Current.Pos.Y, (int)m_Graph.GetNode(EdgeItr.Current.To).Pos.X, (int)m_Graph.GetNode(EdgeItr.Current.To).Pos.Y);
                        }

                    }
                }
            }

            //draw any tree retrieved from the algorithms
            for (int e = 0; e < m_SubTree.Count; ++e)
            {
                if (!NavGraphEdge.IsNull(m_SubTree[e]))
                {
                    Vector2D from = m_Graph.GetNode(m_SubTree[e].From).Pos;
                    Vector2D to = m_Graph.GetNode(m_SubTree[e].To).Pos;

                    objGraphics.DrawLine(Pens.Red, (int)from.X, (int)from.Y, (int)to.X, (int)to.Y);
                }
            }

            //draw the path (if any)  
            if (m_Path.Count > 0)
            {
                for (int i = 0; i < m_Path.Count; ++i)
                {
                    if (i > 0)
                    {
                        Point start = new Point((int)m_Graph.GetNode(m_Path[i - 1]).Pos.X, (int)m_Graph.GetNode(m_Path[i - 1]).Pos.Y);
                        Point end = new Point((int)m_Graph.GetNode(m_Path[i]).Pos.X, (int)m_Graph.GetNode(m_Path[i]).Pos.Y);

                        objGraphics.DrawLine(m_ThickBlue, start, end);
                    }
                }
            }
        }
Exemple #2
0
        public void Render(Graphics objGraphics)
        {
            //render all the cells
            for (int nd = 0; nd < m_Graph.NumNodes(); ++nd)
            {
                int left   = (int)(m_Graph.GetNode(nd).Pos.X - m_dCellWidth / 2.0);
                int top    = (int)(m_Graph.GetNode(nd).Pos.Y - m_dCellHeight / 2.0);
                int right  = (int)(1 + m_Graph.GetNode(nd).Pos.X + m_dCellWidth / 2.0);
                int bottom = (int)(1 + m_Graph.GetNode(nd).Pos.Y + m_dCellHeight / 2.0);

                Rectangle rect = Rectangle.FromLTRB(left, top, right, bottom);

                SolidBrush fillBrush = new SolidBrush(Color.Gray);

                switch (m_TerrainType[nd])
                {
                case (int)brush_type.normal:
                    fillBrush.Color = Color.White;
                    break;

                case (int)brush_type.obstacle:
                    fillBrush.Color = Color.Black;
                    break;

                case (int)brush_type.water:
                    fillBrush.Color = Color.DodgerBlue;
                    break;

                case (int)brush_type.mud:
                    fillBrush.Color = Color.Brown;
                    break;

                default:
                    fillBrush.Color = Color.White;
                    break;
                }//end switch

                objGraphics.FillRectangle(fillBrush, rect);

                if (m_bShowTiles)
                {
                    objGraphics.DrawLine(Pens.Gray, rect.Location, new Point(rect.Right, rect.Top));
                    objGraphics.DrawLine(Pens.Gray, rect.Location, new Point(rect.Left, rect.Bottom));
                }

                if (nd == m_iTargetCell)
                {
                    rect.Inflate(-4, -4);
                    objGraphics.FillRectangle(Brushes.Red, rect);
                    objGraphics.DrawString("T", m_font, Brushes.Black, rect.Right - (int)(rect.Width * 0.75), rect.Y);
                }
                else if (nd == m_iSourceCell)
                {
                    rect.Inflate(-4, -4);
                    objGraphics.FillRectangle(Brushes.LightGreen, rect);
                    objGraphics.DrawString("S", m_font, Brushes.Black, rect.Right - (int)(rect.Width * 0.75), rect.Y);
                }

                //render dots at the corners of the cells
                objGraphics.DrawLine(m_ThickBlack, left, top, left + 1, top + 1);
            }

            //draw the graph nodes and edges if rqd
            if (m_bShowGraph)
            {
                if (m_Graph.NumNodes() > 0)
                {
                    SparseGraph.NodeIterator NodeItr = new SparseGraph.NodeIterator(m_Graph);

                    while (NodeItr.MoveNext())
                    {
                        objGraphics.DrawEllipse(Pens.LightGray, (int)(NodeItr.Current.Pos.X - 2), (int)(NodeItr.Current.Pos.Y - 2), (int)2 * 2, (int)2 * 2);

                        SparseGraph.EdgeIterator EdgeItr = new SparseGraph.EdgeIterator(m_Graph, NodeItr.Current.Index);

                        while (EdgeItr.MoveNext())
                        {
                            objGraphics.DrawLine(Pens.LightGray, (int)NodeItr.Current.Pos.X, (int)NodeItr.Current.Pos.Y, (int)m_Graph.GetNode(EdgeItr.Current.To).Pos.X, (int)m_Graph.GetNode(EdgeItr.Current.To).Pos.Y);
                        }
                    }
                }
            }

            //draw any tree retrieved from the algorithms
            for (int e = 0; e < m_SubTree.Count; ++e)
            {
                if (!NavGraphEdge.IsNull(m_SubTree[e]))
                {
                    Vector2D from = m_Graph.GetNode(m_SubTree[e].From).Pos;
                    Vector2D to   = m_Graph.GetNode(m_SubTree[e].To).Pos;

                    objGraphics.DrawLine(Pens.Red, (int)from.X, (int)from.Y, (int)to.X, (int)to.Y);
                }
            }

            //draw the path (if any)
            if (m_Path.Count > 0)
            {
                for (int i = 0; i < m_Path.Count; ++i)
                {
                    if (i > 0)
                    {
                        Point start = new Point((int)m_Graph.GetNode(m_Path[i - 1]).Pos.X, (int)m_Graph.GetNode(m_Path[i - 1]).Pos.Y);
                        Point end   = new Point((int)m_Graph.GetNode(m_Path[i]).Pos.X, (int)m_Graph.GetNode(m_Path[i]).Pos.Y);

                        objGraphics.DrawLine(m_ThickBlue, start, end);
                    }
                }
            }
        }
        public override bool Search()
        {
            //create an indexed priority queue that sorts smallest to largest
            //(front to back).Note that the maximum number of elements the iPQ
            //may contain is N. This is because no node can be represented on the 
            //queue more than once.
            IndexedPriorityQLow pq = new IndexedPriorityQLow(m_FCosts, m_Graph.NumNodes());

            //put the source node on the queue
            pq.insert(m_iSource);

            //while the queue is not empty
            while (!pq.empty())
            {
                //get lowest cost node from the queue. 
                int NextClosestNode = pq.Pop();

                //move this node from the frontier to the spanning tree
                m_ShortestPathTree[NextClosestNode] = m_SearchFrontier[NextClosestNode];

                //if the target has been found exit
                if (NextClosestNode == m_iTarget) return true;

                //now to relax the edges.
                SparseGraph.EdgeIterator EdgeItr = new SparseGraph.EdgeIterator(m_Graph, NextClosestNode);

                while (EdgeItr.MoveNext())
                {
                    //calculate the heuristic cost from this node to the target (H)                       
                    double HCost = funcPointer(m_Graph, m_iTarget, EdgeItr.Current.To);

                    //calculate the 'real' cost to this node from the source (G)
                    double GCost = m_GCosts[NextClosestNode] + EdgeItr.Current.Cost;

                    //if the node has not been added to the frontier, add it and update
                    //the G and F costs
                    if (NavGraphEdge.IsNull(m_SearchFrontier[EdgeItr.Current.To]))
                    {
                        m_FCosts[EdgeItr.Current.To] = GCost + HCost;
                        m_GCosts[EdgeItr.Current.To] = GCost;

                        pq.insert(EdgeItr.Current.To);

                        m_SearchFrontier[EdgeItr.Current.To] = EdgeItr.Current;
                    }
                    //if this node is already on the frontier but the cost to get here
                    //is cheaper than has been found previously, update the node
                    //costs and frontier accordingly.
                    else if ((GCost < m_GCosts[EdgeItr.Current.To]) && NavGraphEdge.IsNull(m_ShortestPathTree[EdgeItr.Current.To]))
                    {
                        m_FCosts[EdgeItr.Current.To] = GCost + HCost;
                        m_GCosts[EdgeItr.Current.To] = GCost;

                        pq.ChangePriority(EdgeItr.Current.To);

                        m_SearchFrontier[EdgeItr.Current.To] = EdgeItr.Current;
                    }
                }
            }
            return false;
        }
        public override bool Search()
        {
            //create a std stack of edges
            Stack<NavGraphEdge> stack = new Stack<NavGraphEdge>();

            //create a dummy edge and put on the stack
            NavGraphEdge Dummy = new NavGraphEdge(m_iSource, m_iSource, 0);

            stack.Push(Dummy);

            //while there are edges in the stack keep searching
            while (stack.Count > 0)
            {
                //grab and remove the next edge
                NavGraphEdge NextEdge = stack.Pop();

                //make a note of the parent of the node this edge points to
                m_Route[NextEdge.To] = NextEdge.From;

                //put it on the tree. (making sure the dummy edge is not placed on the tree)
                if (NextEdge != Dummy)
                {
                    m_SpanningTree.Add(NextEdge);
                }

                //and mark it visited
                m_Visited[NextEdge.To] = (int)NodeState.visited;

                //if the target has been found the method can return success
                if (NextEdge.To == m_iTarget)
                {
                    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)

                SparseGraph.EdgeIterator EdgeItr = new SparseGraph.EdgeIterator(m_Graph, NextEdge.To);

                while (EdgeItr.MoveNext())
                {
                    if (m_Visited[EdgeItr.Current.To] == (int)NodeState.unvisited)
                    {
                        stack.Push(EdgeItr.Current);
                    }

                }
            }

            //no path to target
            return false;
        }
        public override bool Search()
        {
            //create an indexed priority queue that sorts smallest to largest
            //(front to back).Note that the maximum number of elements the iPQ
            //may contain is N. This is because no node can be represented on the 
            //queue more than once.
            IndexedPriorityQLow pq = new IndexedPriorityQLow(m_CostToThisNode, m_Graph.NumNodes());

            //put the source node on the queue
            pq.insert(m_iSource);

            //while the queue is not empty
            while (!pq.empty())
            {
                //get lowest cost node from the queue. Don't forget, the return value
                //is a *node index*, not the node itself. This node is the node not already
                //on the SPT that is the closest to the source node
                int NextClosestNode = pq.Pop();

                //move this edge from the frontier to the shortest path tree
                m_ShortestPathTree[NextClosestNode] = m_SearchFrontier[NextClosestNode];

                //if the target has been found exit
                if (NextClosestNode == m_iTarget) return true;

                //now to relax the edges.
                SparseGraph.EdgeIterator EdgeItr = new SparseGraph.EdgeIterator(m_Graph, NextClosestNode);

                while (EdgeItr.MoveNext())
                {
                    //the total cost to the node this edge points to is the cost to the
                    //current node plus the cost of the edge connecting them.
                    double NewCost = m_CostToThisNode[NextClosestNode] + EdgeItr.Current.Cost;

                    //if this edge has never been on the frontier make a note of the cost
                    //to get to the node it points to, then add the edge to the frontier
                    //and the destination node to the PQ.
                    if (NavGraphEdge.IsNull(m_SearchFrontier[EdgeItr.Current.To]))
                    {
                        m_CostToThisNode[EdgeItr.Current.To] = NewCost;

                        pq.insert(EdgeItr.Current.To);

                        m_SearchFrontier[EdgeItr.Current.To] = EdgeItr.Current;
                    }

                    //else test to see if the cost to reach the destination node via the
                    //current node is cheaper than the cheapest cost found so far. If
                    //this path is cheaper, we assign the new cost to the destination
                    //node, update its entry in the PQ to reflect the change and add the
                    //edge to the frontier
                    else if ((NewCost < m_CostToThisNode[EdgeItr.Current.To]) &&
                              NavGraphEdge.IsNull(m_ShortestPathTree[EdgeItr.Current.To]))
                    {
                        m_CostToThisNode[EdgeItr.Current.To] = NewCost;

                        //because the cost is less than it was previously, the PQ must be
                        //re-sorted to account for this.
                        pq.ChangePriority(EdgeItr.Current.To);

                        m_SearchFrontier[EdgeItr.Current.To] = EdgeItr.Current;
                    }
                }
            }
            return false;
        }