/* Distance Euclidienne * Retourne la distance euclidienne au carré, qui permet de gagner du temps car on ne calcul pas la racine */ static public int SquareDistanceTo(ASCase CaseA, ASCase CaseB) { return(SquareDistanceTo(CaseA.Point, CaseB.Point)); /*(int)Math.Pow(Case.Point.X - CaseA.Point.X, 2) + * (int)Math.Pow(Case.Point.Y - CaseA.Point.Y, 2);*/ }
public PositionElement ConvertFromCase(ASCase Case) { PositionElement Position = new PositionElement(); Position.X = (int)(Case.Point.X * _UnitByCol); Position.Y = (int)(Case.Point.Y * _UnitByRow); return(Position); }
public ASCase ConvertToCase(PositionElement point) { ASCase Case = new ASCase((point.X / (int)_UnitByCol), (point.Y / (int)_UnitByRow)); /* Case.Visited = false; * Case.Contenu = ASCaseState.NONE; * Case.X = point.X / _UnitByCol; * Case.Y = point.Y / _UnitbyRow;*/ return(Case); }
public System.Drawing.Rectangle CalculerRectangle(PositionElement point) { ASCase p = this.ConvertToCase(point); //ASCase Case = _map.getCase(p.X, p.Y); PositionElement HautGauche = ConvertFromCase(p); p.Point.X++; p.Point.Y++; PositionElement BasDroite = ConvertFromCase(p); System.Drawing.Rectangle rect = new System.Drawing.Rectangle(HautGauche.X, HautGauche.Y, BasDroite.X - HautGauche.X, BasDroite.Y - HautGauche.Y); return(rect); }
public ASMap(int lignes, int colonnes) { _map = new ASCase[lignes, colonnes]; _lignes = lignes; _colonnes = colonnes; _obstacles = new List <ASCase>(); // Intialisation des indexs for (int x = 0; x < lignes; x++) { for (int y = 0; y < colonnes; y++) { _map[x, y] = new ASCase(x, y); } } }
public AStar(PositionElement Depart, PositionElement Arrivee, PositionZoneTravail ZoneTravail) { _open = new SortedNodeList <ASCase>(); _close = new NodeList <ASCase>(); _UnitByCol = (float)Math.Abs(ZoneTravail.A.X - ZoneTravail.B.X) / _NumCol; _UnitByRow = (float)Math.Abs(ZoneTravail.A.Y - ZoneTravail.B.Y) / _NumRow; _map = new ASMap(_NumCol, _NumRow); ASCase Start = ConvertToCase(Depart); ASCase End = ConvertToCase(Arrivee); _map.setStart(Start.Point.X, Start.Point.Y); _map.setEnd(End.Point.X, End.Point.Y); }
// Trouve la case la plus proche dans la bonne direction // Prend en compte les cases déja visitées /*private ASCase FindNearestInDirection(ASCase current) * { * List<ASCase> ListValide = new List<ASCase>(); * ASCase CaseOut = null; * * // Parcours toute les direction * for (int i = 0; i < 4; i++) * { * ASCase Case = _map.getAdjCase(current, i); * if (Case == null) * continue; * * if( Case.Contenu == ASCaseState.END) // Fin * { * ListValide.Add(Case); * return Case; * } * * if (!Case.Visited) // Case valide * { * if (Case.Contenu == ASCaseState.OBSTACLE) * continue; * _map.setVisited(Case.X, Case.Y); * ListValide.Add(Case); * } * } * * foreach (ASCase Case in ListValide) * { * * if (CaseOut == null) * CaseOut = Case; * else * { * double distance1 = CaseOut.DistanceTo(_map.End); * double distance2 = Case.DistanceTo(_map.End); * if (distance1 > distance2) // Elle est plus proche * CaseOut = Case; * } * } * * return CaseOut; * } */ /*public Track CalculerTrajectoire() * { * ASCase PositionCourante = _map.Start; * List<ASCase> ListeDeplacement = new List<ASCase>(); * ListeDeplacement.Add(PositionCourante); * Track Trajectoire = new Track(); * while (PositionCourante.Contenu != ASCaseState.END) // Tant qu'on a pas trouver * { * ASCase Case = FindNearestInDirection(PositionCourante); * if (Case != null) // On a trouver une case , on l'ajoute et on avance * { * //_map.setVisited(Case.X, Case.Y); * ListeDeplacement.Add(Case); * PositionCourante = Case; * } * else * { * ASCase Precedente = ListeDeplacement.Last(); * PositionCourante = Precedente; // On recommence a la derniere place * ListeDeplacement.Remove(Precedente); // On le retire de la liste de déplacement * } * * } * * foreach (ASCase Ajout in ListeDeplacement) * Trajectoire.ajouterPoint(ConvertFromCase(Ajout)); * //Trajectoire.ajouterPoints(ListeDeplacement); * return Trajectoire; * } * */ // Ajouter dans la liste des noeuds a visiter private void AddToOpen(ASCase courant, IEnumerable <ASCase> fils) { foreach (ASCase Casefille in fils) { if (!this._open.Contains(Casefille)) // Pas deja dans la liste { if (!this._close.Contains(Casefille)) // Pas déja traité { this._open.AddDichotomatic(Casefille); // Ajout dans les traitemant furtur } } else { if (Casefille.CalculCout() < this._open[Casefille].G) // Si on a un chemin plus court { Casefille.Parent = courant; // Mettre a jour le parent si on y accede plus rapidement Casefille.G = courant.G + 1; } } } }
// Calcul de la trajectoire public Track CalculerTrajectoire() { this._open.Add(_map.Start); while (this._open.Count > 0) { ASCase best = this._open.RemoveFirst(); if (best.Point == _map.End.Point) { Track sol = new Track(); // Solution while (best.Parent != null) // on remonte la hierarchie { sol.ajouterPoint(ConvertFromCase(best)); // Ajout dans la solution best = best.Parent; // Remonte } return(sol); } this._close.Add(best); this.AddToOpen(best, _map.getAdjCase(best, true)); } return(null); // Pas de trouvé }
public void AjouterObstacle(ASCase Case) { _obstacles.Add(Case); }
public void setEnd(int pLigne, int pColonne) { _end = _map[pLigne, pColonne]; //_end.Contenu = ASCaseState.END; //_end.Visited = false; }
public void setStart(int pLigne, int pColonne) { _start = _map[pLigne, pColonne]; //_start.Contenu = ASCaseState.START; //_start.Visited = false; }
public List <ASCase> getAdjCase(ASCase current, bool bdiagonales = false) { List <ASCase> list = new List <ASCase>(); ASPoint Point = new ASPoint(); // Haut Point.X = current.Point.X; Point.Y = current.Point.Y + 1; if (inMap(Point) && NearMovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 1; list.Add(Case); } // Droite Point.X = current.Point.X + 1; Point.Y = current.Point.Y; if (inMap(Point) && NearMovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 1; list.Add(Case); } // Gauche Point.X = current.Point.X - 1; Point.Y = current.Point.Y; if (inMap(Point) && NearMovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 1; list.Add(Case); } // Bas Point.X = current.Point.X; Point.Y = current.Point.Y - 1; if (inMap(Point) && NearMovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 1; list.Add(Case); } if (bdiagonales) { // Haut gauche Point.X = current.Point.X - 1; Point.Y = current.Point.Y + 1; if (inMap(Point) && MovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 2; list.Add(Case); } // Haut Droite Point.X = current.Point.X + 1; Point.Y = current.Point.Y + 1; if (inMap(Point) && MovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 2; list.Add(Case); } // Bas Gauche Point.X = current.Point.X - 1; Point.Y = current.Point.Y - 1; if (inMap(Point) && MovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 2; list.Add(Case); } // Bas Droite Point.X = current.Point.X + 1; Point.Y = current.Point.Y - 1; if (inMap(Point) && MovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 2; list.Add(Case); } } return(list); }
public void AddObstacle(PositionElement point) { ASCase Case = ConvertToCase(point); _map.AjouterObstacle(Case); }
public ASCase(ASPoint point, ASCase parent) { this.Point = point; this.Parent = parent; }
/*public void SetG(int G) * { * this._G = G; * }*/ /*public void CalculHF(ASCase End) * { * CalculH(End); * this._F = this._G + this._H; * }*/ public int CalculH(ASCase End) { this._H = SquareDistanceTo(this, End); return(this._H); }
public bool NearFree(ASPoint point) { return(!_obstacles.Exists(ASCase.Proche(point, 1))); }
public bool MovementFree(ASPoint point) { return(!_obstacles.Exists(ASCase.byPos(point))); }
public ASCase(int X, int Y, int G, ASCase end) : this(X, Y, G) { this.CalculH(end); }