Ejemplo n.º 1
0
 /// <summary>
 /// This method returns a double representing the length of time (in seconds) that it would
 /// take to get to from a PseudoNode to a Node along the same Path. If the given Node is
 /// not on the same Path, this returns Double.MAX_VALUE as this method contains no support
 /// for routing.
 /// </summary>
 /// <param name="node"></param>
 /// <param name="pseudoNode"></param>
 /// <returns></returns>
 public double GetTimeToNodeFrom(Node node, PseudoNode pseudoNode)
 {
     if (pseudoNode.GetPath() == this)
     {
         return(GetTimeToNodeFrom(node, pseudoNode.GetDistanceAlongPath()));
     }
     else
     {
         Debug.WriteLine("The PseudoNode does not lie on this Path.");
         return(Double.MaxValue);
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// This method returns a double that represents the length of time (in seconds) that it
        /// would take to get from one PseudoNode on the Path to another on the Path. If one of
        /// the nodes is not on this Path, this method will return Double.MaxValue.
        /// </summary>
        /// <param name="destination_node"></param>
        /// <param name="source_node"></param>
        /// <returns></returns>
        public double GetTimeToPseudoNodeFrom(PseudoNode destination_node, PseudoNode source_node)
        {
            // Check both PseudoNodes are on the Path
            if (destination_node.GetPath() != this || source_node.GetPath() != this)
            {
                return(Double.MaxValue);
            }

            // Calculate length of time
            double destination_distance = destination_node.GetDistanceAlongPath();
            double source_distance      = source_node.GetDistanceAlongPath();
            double time = (destination_distance - source_distance) / speed_limit;

            time = (time > 0) ? time : -time;
            return(time);
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Sets up a PseudoNode at the same point as the given PseudoNode.
 /// </summary>
 /// <param name="node"></param>
 public PseudoNode(PseudoNode node)
 {
     path = node.GetPath();
     distance_along_path = node.GetDistanceAlongPath();
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Initialises a Route by giving a start and end PseudoNode, and calculates the quickest Route between them.
        /// </summary>
        /// <param name="_source_node"></param>
        /// <param name="_end_node"></param>
        public Route(PseudoNode _source_node, PseudoNode _end_node)
        {
            // Storing the source and destination nodes
            source_node = new PseudoNode(_source_node);
            end_node    = new PseudoNode(_end_node);

            Node [] source_nodes     = source_node.GetPath().GetNodes();
            Node [] end_nodes        = end_node.GetPath().GetNodes();
            bool [] end_nodes_mapped = { false, false };

            List <NodeAndTime> nodes_and_times = new List <NodeAndTime>();
            List <Node>        nodes           = Map.GetNodes();

            // Setting the initial times to get to each node from the source node
            foreach (Node node in nodes)
            {
                if (node == source_nodes[0] || node == source_nodes[1])
                {
                    nodes_and_times.Add(new NodeAndTime(node, source_node.GetPath().GetTimeToNodeFrom(node, source_node)));
                }
                else
                {
                    nodes_and_times.Add(new NodeAndTime(node, false));
                }
            }

            // Implementing Dijkstra's algorithm:

            bool complete = false;

            while (!complete)
            {
                // Sort to ensure that the nearest (by time) nodes to the source node are at the top of the List
                Sort(nodes_and_times);

                // Finding the next node that has not been mapped
                NodeAndTime analysis_node = null;
                foreach (NodeAndTime node_and_time in nodes_and_times)
                {
                    if (!node_and_time.AdjacentNodesMapped())
                    {
                        analysis_node = node_and_time;
                        break;
                    }
                }

                // If all nodes have been mapped, then the analysis_node was not set in the previous code snippet.
                // Hence we need not run the rest of the loop and we can finish the while loop. This is a fail safe
                // to ensure that the code does not crash. In ordinary circumstances, this scenario should be
                // handled below, at the bottom of the while loop.
                if (analysis_node == null)
                {
                    complete = true;
                    continue;
                }

                // Get adjacent nodes
                List <Node> adj_nodes_temp = Map.GetNodesAdjacentToNode(analysis_node.GetNode());

                foreach (Node node in adj_nodes_temp)
                {
                    // Calculate time coming from this node
                    double new_time = Map.GetPathWithNodes(analysis_node.GetNode(), node).GetTime() + analysis_node.GetTime();

                    // If the time lower than it would be taking the previous route here, change that NodeAndTime object to come through this way instead
                    NodeAndTime previous_node_and_time = GetNodeAndTime(node, nodes_and_times);
                    if (new_time < previous_node_and_time.GetTime())
                    {
                        List <NodeAndTime> new_shortest_route = new List <NodeAndTime>(analysis_node.GetShortestRouteToNodeForCalc());
                        new_shortest_route.Add(analysis_node);
                        previous_node_and_time.SetShortestRouteToNode(new_shortest_route);
                        previous_node_and_time.SetTime(new_time);
                    }
                }
                analysis_node.SetAdjacentNodesMapped(true);

                // Check if both Nodes either side of the PseudoNode have been analysed.
                if (analysis_node.GetNode() == end_nodes[0])
                {
                    end_nodes_mapped[0] = true;
                }
                else if (analysis_node.GetNode() == end_nodes[1])
                {
                    end_nodes_mapped[1] = true;
                }

                // Completing the loop if both of the end Nodes have been mapped
                if (end_nodes_mapped[0] && end_nodes_mapped[1])
                {
                    complete = true;
                }
            }

            // Getting the time that it will take to get to the PseudoNode via both Nodes either side of the containing Route
            NodeAndTime [] end_node_and_times   = { GetNodeAndTime(end_nodes[0], nodes_and_times), GetNodeAndTime(end_nodes[1], nodes_and_times) };
            double         time_from_end_node_1 = end_node_and_times[0].GetTime() + end_node.GetPath().GetTimeToNodeFrom(end_node_and_times[0].GetNode(), end_node);
            double         time_from_end_node_2 = end_node_and_times[1].GetTime() + end_node.GetPath().GetTimeToNodeFrom(end_node_and_times[1].GetNode(), end_node);

            // Selecting to go through the Node that will give the shortest time, and converting these to a list of Nodes.
            if (time_from_end_node_1 <= time_from_end_node_2)
            {
                node_route = end_node_and_times[0].ConvertToListOfNodes();
                path_route = end_node_and_times[0].ConvertToListOfPaths();
            }
            else
            {
                node_route = end_node_and_times[1].ConvertToListOfNodes();
                path_route = end_node_and_times[1].ConvertToListOfPaths();
            }

            // Adding start and end Paths on as they may not currently be there
            if (path_route.Count == 0)
            {
                path_route.Add(source_node.GetPath());
            }
            if (path_route[0] != source_node.GetPath())
            {
                path_route.Insert(0, source_node.GetPath());
            }
            if (path_route[path_route.Count - 1] != end_node.GetPath())
            {
                path_route.Add(end_node.GetPath());
            }

            // Determine which directions the Paths should be travelled in
            DetermineDirections();
        }
Ejemplo n.º 5
0
 /// <summary>
 /// This method returns a Direction that specifies whether the Path that the PseudoNode is on should be travelled
 /// forwards or backwards (i.e. from Path.GetNodes()[0] to Path.GetNodes()[1] or vice versa). If the PseudoNode
 /// does not sit on a Path in this Route, this method will return Direction.FORWARDS.
 /// </summary>
 /// <param name="pseudo_node"></param>
 /// <returns></returns>
 public Direction GetDirection(PseudoNode pseudo_node)
 {
     return(GetDirection(pseudo_node.GetPath()));
 }
Ejemplo n.º 6
0
 /// <summary>
 /// This method finds the next Path on the Route by the current position of the PseudoNode. If the PseudoNode is
 /// not on the Route, or if it lies on the last Path in the Route, this method will return null.
 /// </summary>
 /// <param name="current_position"></param>
 /// <returns></returns>
 public Path GetNextPath(PseudoNode current_position)
 {
     return(GetNextPath(current_position.GetPath()));
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Returns the Path that the user is currently on.
 /// </summary>
 /// <returns></returns>
 public Path GetCurrentPath()
 {
     return(position.GetPath());
 }