public Track(Track PreviousTrack, Arc Transition) { if (_Target==null) throw new InvalidOperationException("You must specify a target Node for the Track class."); Queue = PreviousTrack; _Cost = Queue.Cost + Transition.Cost; _NbArcsVisited = Queue._NbArcsVisited + 1; EndNode = Transition.EndNode; }
/// <summary> /// Directly Adds an arc to the graph. /// </summary> /// <exception cref="ArgumentException">Cannot add an arc if one of its extremity nodes does not belong to the graph.</exception> /// <param name="NewArc">The arc to add.</param> /// <returns>'true' if it has actually been added / 'false' if the arc is null or if it is already in the graph.</returns> public bool AddArc(Arc NewArc) { //if ( NewArc==null || LA.Contains(NewArc) ) return false; if (NewArc == null) return false; if (!LN.Contains(NewArc.StartNode) || !LN.Contains(NewArc.EndNode)) throw new ArgumentException("Cannot add an arc if one of its extremity nodes does not belong to the graph."); LA.Add(NewArc); return true; }
/// <summary> /// Removes a node from the graph as well as the linked arcs. /// </summary> /// <param name="ArcToRemove">The arc to remove.</param> /// <returns>'true' if succeeded / 'false' otherwise.</returns> public bool RemoveArc(Arc ArcToRemove) { if (ArcToRemove == null) return false; try { LA.Remove(ArcToRemove); ArcToRemove.StartNode.OutgoingArcs.Remove(ArcToRemove); ArcToRemove.EndNode.IncomingArcs.Remove(ArcToRemove); } catch { return false; } return true; }
/// <summary> /// Retourne vrai si le noeud peut se lier avec au moins un autre noeud du graph /// </summary> /// <param name="node"></param> /// <param name="obstacles"></param> /// <param name="distanceSecurite"></param> /// <param name="distanceMax"></param> /// <returns></returns> public bool Raccordable(Node node, List<IForme> obstacles, double distanceSecurite, double distanceMax) { foreach (Node no in Nodes) { if (node != no) { double distance = Math.Sqrt((node.Position.X - no.Position.X) * (node.Position.X - no.Position.X) + (node.Position.Y - no.Position.Y) * (node.Position.Y - no.Position.Y)); if (distance < distanceMax) { Arc arc = new Arc(no, node); arc.Weight = Math.Sqrt(distance); Arc arc2 = new Arc(node, no); arc2.Weight = Math.Sqrt(distance); foreach (IForme obstacle in obstacles) { if (obstacle.Distance(new Segment(new PointReel(no.X, no.Y), new PointReel(node.X, node.Y))) < distanceSecurite) { arc.Passable = false; arc2.Passable = false; break; } } if (arc.Passable) { return true; } } } } return false; }
/// <summary> /// Ajoute un noeud au graph en reliant tous les points à une distance maximale et en prenant en compte les obstacles à éviter /// Si permanent == false, le point sera supprimé au prochain appel de @CleanNodesArcsAdd /// </summary> /// <param name="node">Noeud à ajouter</param> /// <param name="obstacles">Obstacles à éviter</param> /// <param name="distanceSecurite">Distance (mm) de sécurité auour des obstacles</param> /// <param name="distanceMax">Distance (mm) max de liaison avec les autres noeuds</param> /// <param name="permnant">True si le point est ajouté de façon permanente et donc ne sera pas supprimé au prochain appel de @CleanNodesArcsAdd</param> /// <returns>Nombre de points reliés au point ajouté</returns> public int AddNode(Node node, List<IForme> obstacles, double distanceSecurite, double distanceMax, bool permanent = false) { double distanceNode; // Si un noeud est deja présent à cet endroit on ne l'ajoute pas ClosestNode(node.X, node.Y, node.Z, out distanceNode, true); if (distanceNode == 0) return 0; // Teste si le noeud est franchissable avec la liste des obstacles foreach (IForme obstacle in Plateau.ObstaclesPlateau) { if (obstacle.Distance(new PointReel(node.X, node.Y)) < distanceSecurite) { node.Passable = false; return 0; } } Nodes.Add(node); if(!permanent) nodesAdd.Add(node); int nbLiaisons = 0; // Liaisons avec les autres noeuds du graph foreach (Node no in Nodes) { if (node != no) { double distance = Math.Sqrt((node.Position.X - no.Position.X) * (node.Position.X - no.Position.X) + (node.Position.Y - no.Position.Y) * (node.Position.Y - no.Position.Y)); if (distance < distanceMax) { Arc arc = new Arc(no, node); arc.Weight = Math.Sqrt(distance); Arc arc2 = new Arc(node, no); arc2.Weight = Math.Sqrt(distance); foreach (IForme obstacle in obstacles) { if (obstacle.Distance(new Segment(new PointReel(no.X, no.Y), new PointReel(node.X, node.Y))) < distanceSecurite) { arc.Passable = false; arc2.Passable = false; break; } } if (arc.Passable) { AddArc(arc); AddArc(arc2); if (!permanent) { arcsAdd.Add(arc); arcsAdd.Add(arc2); } nbLiaisons++; } } } } return nbLiaisons; }
/// <summary> /// Creates an arc between two nodes that are already registered in the graph, adds it to the graph and returns its reference. /// </summary> /// <exception cref="ArgumentException">Cannot add an arc if one of its extremity nodes does not belong to the graph.</exception> /// <param name="StartNode">Start node for the arc.</param> /// <param name="EndNode">End node for the arc.</param> /// <param name="Weight">Weight for the arc.</param> /// <returns>The reference of the new arc / null if the arc is already in the graph.</returns> public Arc AddArc(Node StartNode, Node EndNode, float Weight) { Arc NewArc = new Arc(StartNode, EndNode); NewArc.Weight = Weight; return AddArc(NewArc) ? NewArc : null; }