public bool ParcourirTrajectoire(Trajectoire traj) { TrajectoireEnCours = traj; DateTime debut = DateTime.Now; Console.WriteLine("Lancement traj"); TrajectoireCoupee = false; TrajectoireEchouee = false; foreach (IAction action in traj.ToActions()) { action.Executer(); if (TrajectoireCoupee || TrajectoireEchouee) break; if ( action is ActionAvance || action is ActionRecule) { Historique.Log("Noeud atteint " + TrajectoireEnCours.PointsPassage[0].X + ":" + TrajectoireEnCours.PointsPassage[0].Y, TypeLog.PathFinding); TrajectoireEnCours.PointsPassage.RemoveAt(0); TrajectoireEnCours.Segments.RemoveAt(0); } } Console.WriteLine("Traj terminée"); if(!TrajectoireCoupee && !TrajectoireEchouee) { Historique.Log("Trajectoire parcourue en " + Math.Round((((DateTime.Now - debut).TotalMilliseconds) / 1000.0), 1) + "s", TypeLog.PathFinding); Console.WriteLine("Temps prévu :" + traj.Duree + "ms / Temps effectif : " + (DateTime.Now - debut).TotalMilliseconds + "ms"); if(semTrajectoire != null) semTrajectoire.Release(); TrajectoireEnCours = null; return true; } if(TrajectoireEchouee) { Historique.Log("Echec du parcours de la trajectoire (dérapage, blocage...)", TypeLog.PathFinding); if (semTrajectoire != null) semTrajectoire.Release(); TrajectoireEnCours = null; return true; } TrajectoireEnCours = null; if (semTrajectoire != null) semTrajectoire.Release(); return false; }
public bool ObstacleTest() { if (TrajectoireCoupee) return false; try { // Teste si le chemin en cours de parcours est toujours franchissable if (TrajectoireEnCours != null && TrajectoireEnCours.Segments.Count > 0) { List<Segment> segmentsTrajectoire = new List<Segment>(); // Calcule le segment entre nous et notre destination (permet de ne pas considérer un obstacle sur un tronçon déjà franchi) Segment seg = new Segment(Position.Coordonnees, new PointReel(TrajectoireEnCours.Segments[0].Fin)); segmentsTrajectoire.Add(seg); for (int iSegment = 1; iSegment < TrajectoireEnCours.Segments.Count; iSegment++) { segmentsTrajectoire.Add(TrajectoireEnCours.Segments[iSegment]); } Synchronizer.Lock(Plateau.ObstaclesBalise); foreach (IForme forme in Plateau.ObstaclesBalise) { foreach (Segment segment in segmentsTrajectoire) { // Marge de 30mm pour être plus permissif sur le passage te ne pas s'arreter dès que l'adversaire approche if (TropProche(seg, forme, - 30)) { // Demande de génération d'une nouvelle trajectoire Historique.Log("Trajectoire coupée, annulation", TypeLog.PathFinding); TrajectoireCoupee = true; TrajectoireEnCours = null; if (DeplacementLigne) Stop(); Synchronizer.Unlock(Plateau.ObstaclesBalise); return false; } } } Synchronizer.Unlock(Plateau.ObstaclesBalise); } } catch (Exception) { return false; } return true; }
private static void DessineTrajectoire(Trajectoire traj, Graphics g) { Point pointNodePrec = traj.PointsPassage[0]; using (Pen penR = new Pen(Color.Red, 2), penB = new Pen(Color.White, 4)) { for (int i = 0; i < traj.PointsPassage.Count; i++) { Point pointNode = RealToScreenPosition(traj.PointsPassage[i].X, traj.PointsPassage[i].Y); if (i >= 1) { g.DrawLine(penB, pointNode, pointNodePrec); g.DrawLine(penR, pointNode, pointNodePrec); } pointNodePrec = pointNode; } for (int i = 0; i < traj.PointsPassage.Count; i++) { Point pointNode = RealToScreenPosition(traj.PointsPassage[i].X, traj.PointsPassage[i].Y); g.FillEllipse(brushRouge, new Rectangle(pointNode.X - 4, pointNode.Y - 4, 8, 8)); g.DrawEllipse(penBlanc, new Rectangle(pointNode.X - 4, pointNode.Y - 4, 8, 8)); } } }
public static Trajectoire ChercheTrajectoire(Graph graph, List<IForme> obstacles, Position positionActuell, Position destination, double rayonSecurite, double distanceSecuriteCote) { DateTime debut = DateTime.Now; double distanceRaccordable = 150; double distance; bool cheminTrouve = false; bool raccordable = false; Trajectoire trajectoire = new Trajectoire(); trajectoire.AngleDepart = new Angle(positionActuell.Angle); trajectoire.AngleFinal = new Angle(destination.Angle); PointsTrouves = new List<PointReel>(); PointsTrouves.Add(new PointReel(positionActuell.Coordonnees)); trajectoire.AjouterPoint(new PointReel(positionActuell.Coordonnees)); Synchronizer.Lock(graph); int nbPointsDepart = 0; int nbPointsArrivee = 0; Node debutNode; Node nodeProche = graph.ClosestNode(positionActuell.Coordonnees.X, positionActuell.Coordonnees.Y, 0, out distance, false); if (distance != 0) { debutNode = new Node(positionActuell.Coordonnees.X, positionActuell.Coordonnees.Y, 0); nbPointsDepart = graph.AddNode(debutNode, obstacles, rayonSecurite, distanceRaccordable); } else debutNode = nodeProche; if (nbPointsDepart == 0) { // On ne peut pas partir de là où on est Position positionTestee = new Position(positionActuell); bool franchissable = true; // Boucle jusqu'à trouver un point qui se connecte au graph jusqu'à 1m devant int i; for (i = 0; i < 100 && !raccordable; i += 1) { positionTestee.Avancer(10); debutNode = new Node(positionTestee.Coordonnees.X, positionTestee.Coordonnees.Y, 0); raccordable = graph.Raccordable(debutNode, obstacles, rayonSecurite, distanceRaccordable); } // Le point à i*10 mm devant nous est reliable au graph, on cherche à l'atteindre if (raccordable) { Segment segmentTest = new Segment(new PointReel(positionTestee.Coordonnees), new PointReel(positionActuell.Coordonnees)); // Test des obstacles Synchronizer.Lock(Plateau.ObstaclesBalise); foreach (IForme obstacle in obstacles) { if (obstacle.Distance(segmentTest) < distanceSecuriteCote) { franchissable = false; // Si l'obstacle génant est un adversaire, on diminue petit à petit son rayon pour pouvoir s'échapper au bout d'un moment if (Plateau.ObstaclesBalise.Contains(obstacle) && Plateau.RayonAdversaire > 50) { Robots.GrosRobot.Historique.Log("Adversaire au contact, impossible de s'enfuir, réduction du périmètre adverse", TypeLog.PathFinding); Plateau.RayonAdversaire -= 10; } } } Synchronizer.Unlock(Plateau.ObstaclesBalise); // Si le semgent entre notre position et le graph relié au graph est parcourable on y va ! if (franchissable) { PointsTrouves.Add(new PointReel(positionTestee.Coordonnees)); trajectoire.AjouterPoint(new PointReel(positionTestee.Coordonnees)); debutNode = new Node(positionTestee.Coordonnees.X, positionTestee.Coordonnees.Y, 0); nbPointsDepart = graph.AddNode(debutNode, obstacles, rayonSecurite, distanceRaccordable); } } else franchissable = false; // Si toujours pas, on teste en marche arrière if (!franchissable) { franchissable = true; nbPointsDepart = 0; positionTestee = new Position(positionActuell); for (i = 0; i > -100 && !raccordable; i--) { positionTestee.Avancer(-10); debutNode = new Node(positionTestee.Coordonnees.X, positionTestee.Coordonnees.Y, 0); raccordable = graph.Raccordable(debutNode, obstacles, rayonSecurite, distanceRaccordable); } // Le point à i*10 mm derrière nous est reliable au graph, on cherche à l'atteindre if (raccordable) { Segment segmentTest = new Segment(new PointReel(positionTestee.Coordonnees), new PointReel(destination.Coordonnees)); Synchronizer.Lock(Plateau.ObstaclesBalise); // Test des obstacles foreach (IForme obstacle in obstacles) { if (obstacle.Distance(segmentTest) < distanceSecuriteCote) { franchissable = false; // Si l'obstacle génant est un adversaire, on diminue petit à petit son rayon pour pouvoir s'échapper au bout d'un moment if (Plateau.ObstaclesBalise.Contains(obstacle) && Plateau.RayonAdversaire > 50) { Robots.GrosRobot.Historique.Log("Adversaire au contact, impossible de s'enfuir, réduction du périmètre adverse", TypeLog.PathFinding); Plateau.RayonAdversaire -= 10; } } } Synchronizer.Unlock(Plateau.ObstaclesBalise); // Si le semgent entre notre position et le graph relié au graph est parcourable on y va ! if (franchissable) { PointsTrouves.Add(new PointReel(positionTestee.Coordonnees)); trajectoire.AjouterPoint(new PointReel(positionTestee.Coordonnees)); debutNode = new Node(positionTestee.Coordonnees.X, positionTestee.Coordonnees.Y, 0); nbPointsDepart = graph.AddNode(debutNode, obstacles, rayonSecurite, distanceRaccordable); } } } } Node finNode = graph.ClosestNode(destination.Coordonnees.X, destination.Coordonnees.Y, 0, out distance, false); if (distance != 0) { finNode = new Node(destination.Coordonnees.X, destination.Coordonnees.Y, 0); nbPointsArrivee = graph.AddNode(finNode, obstacles, rayonSecurite, distanceRaccordable); } if (nbPointsArrivee == 0) { Console.WriteLine("Blocage arrivée : " + (DateTime.Now - debut).TotalMilliseconds + "ms"); // On ne peut pas arriver là où on souhaite aller // On teste si on peut faire une approche en ligne // teta ne doit pas être nul sinon c'est qu'on ne maitrise pas l'angle d'arrivée et on ne connait pas l'angle d'approche Position positionTestee = new Position(destination); bool franchissable = true; // Boucle jusqu'à trouver un point qui se connecte au graph jusqu'à 1m devant int i; for (i = 0; i < 100 && !raccordable; i++) { positionTestee.Avancer(10); raccordable = graph.Raccordable(new Node(positionTestee.Coordonnees.X, positionTestee.Coordonnees.Y, 0), obstacles, rayonSecurite, distanceRaccordable); } // Le point à i*10 mm devant nous est reliable au graph, on cherche à l'atteindre if (raccordable) { Segment segmentTest = new Segment(new PointReel(positionTestee.Coordonnees), new PointReel(positionActuell.Coordonnees)); // Test des obstacles foreach (IForme obstacle in obstacles) { if (obstacle.Distance(segmentTest) < distanceSecuriteCote) franchissable = false; } } else franchissable = false; // Si toujours pas, on teste en marche arrière if (!franchissable) { positionTestee = new Position(destination); nbPointsArrivee = 0; for (i = 0; i > -100 && !raccordable; i--) { positionTestee.Avancer(-10); raccordable = graph.Raccordable(new Node(positionTestee.Coordonnees.X, positionTestee.Coordonnees.Y, 0), obstacles, rayonSecurite, distanceRaccordable); } if (raccordable) { franchissable = true; Segment segmentTest = new Segment(new PointReel(positionTestee.Coordonnees), new PointReel(destination.Coordonnees)); // Test des obstacles foreach (IForme obstacle in obstacles) { if (obstacle.Distance(segmentTest) < distanceSecuriteCote) franchissable = false; } } } // Si le semgent entre notre position et le node relié au graph est parcourable on y va ! if (franchissable) { finNode = new Node(positionTestee.Coordonnees.X, positionTestee.Coordonnees.Y, 0); nbPointsArrivee = graph.AddNode(finNode, obstacles, rayonSecurite, distanceRaccordable); } } Synchronizer.Unlock(graph); // Teste s'il est possible d'aller directement à la fin sans passer par le graph bool toutDroit = true; Segment segment = new Segment(new PointReel(debutNode.X, debutNode.Y), new PointReel(finNode.X, finNode.Y)); foreach (IForme forme in obstacles) { if (segment.Distance(forme) < rayonSecurite) { toutDroit = false; break; } } if (toutDroit) { Robots.GrosRobot.Historique.Log("Chemin trouvé : ligne droite", TypeLog.PathFinding); cheminTrouve = true; PointsTrouves.Add(new PointReel(finNode.X, finNode.Y)); trajectoire.AjouterPoint(new PointReel(finNode.X, finNode.Y)); if (destination.Coordonnees.Distance(new PointReel(finNode.X, finNode.Y)) > 1) { PointsTrouves.Add(new PointReel(destination.Coordonnees)); trajectoire.AjouterPoint(new PointReel(destination.Coordonnees)); } } // Sinon on passe par le graph else { Synchronizer.Lock(graph); AStar aStar = new AStar(graph); aStar.DijkstraHeuristicBalance = 1; //Console.WriteLine("Avant pathFinding : " + (DateTime.Now - debut).TotalMilliseconds + "ms"); if (aStar.SearchPath(debutNode, finNode)) { Synchronizer.Unlock(graph); //Console.WriteLine("PathFinding trouvé : " + (DateTime.Now - debut).TotalMilliseconds + "ms"); List<Node> nodes = aStar.PathByNodes.ToList<Node>(); List<Arc> arcs = aStar.PathByArcs.ToList<Arc>(); Robots.GrosRobot.Historique.Log("Chemin trouvé : " + (nodes.Count - 2) + " noeud(s) intermédiaire(s)", TypeLog.PathFinding); CheminEnCoursNoeuds = new List<Node>(); CheminEnCoursArcs = new List<Arc>(); CheminTrouve = new List<Arc>(arcs); NodeTrouve = new List<Node>(nodes); //Console.WriteLine("Début simplification : " + (DateTime.Now - debut).TotalMilliseconds + "ms"); // Simplification du chemin // On part du début et on essaie d'aller au point du plus éloigné au moins éloigné en testant si le passage est possible // Si c'est possible on zappe tous les points entre les deux for (int iNodeDepart = 0; iNodeDepart < nodes.Count - 1; iNodeDepart++) { if (iNodeDepart != 0) { PointsTrouves.Add(new PointReel(nodes[iNodeDepart].X, nodes[iNodeDepart].Y)); trajectoire.AjouterPoint(new PointReel(nodes[iNodeDepart].X, nodes[iNodeDepart].Y)); } CheminEnCoursNoeuds.Add(nodes[iNodeDepart]); bool raccourciPossible = true; for (int iNodeArrivee = nodes.Count - 1; iNodeArrivee > iNodeDepart; iNodeArrivee--) { raccourciPossible = true; Segment racourci = new Segment(new PointReel(nodes[iNodeDepart].X, nodes[iNodeDepart].Y), new PointReel(nodes[iNodeArrivee].X, nodes[iNodeArrivee].Y)); //Arc arcRacourci = new Arc(nodes[iNodeDepart], nodes[iNodeArrivee]); //CheminTest = arcRacourci; //arcRacourci.Passable = false; for (int i = obstacles.Count - 1; i >= 4; i--) // > 4 pour ne pas tester les bordures { IForme forme = obstacles[i]; ObstacleTeste = forme; ObstacleProbleme = null; if (racourci.Distance(forme) < rayonSecurite) { ObstacleProbleme = forme; // Tempo pour l'affichage détaillé de la recherche de trajectoire (option) if (Config.CurrentConfig.AfficheDetailTraj > 0) Thread.Sleep(Config.CurrentConfig.AfficheDetailTraj); raccourciPossible = false; break; } //else if(Config.CurrentConfig.AfficheDetailTraj > 0) // Thread.Sleep(Config.CurrentConfig.AfficheDetailTraj); } if (Config.CurrentConfig.AfficheDetailTraj > 0) Thread.Sleep(Config.CurrentConfig.AfficheDetailTraj); ObstacleTeste = null; if (raccourciPossible) { //CheminEnCoursArcs.Add(arcRacourci); iNodeDepart = iNodeArrivee - 1; break; } } CheminTest = null; if (!raccourciPossible) { //Arc arc = new Arc(nodes[iNodeDepart], nodes[iNodeDepart + 1]); //CheminEnCoursArcs.Add(arc); } } CheminEnCoursNoeuds.Add(nodes[nodes.Count - 1]); PointsTrouves.Add(new PointReel(nodes[nodes.Count - 1].X, nodes[nodes.Count - 1].Y)); trajectoire.AjouterPoint(new PointReel(nodes[nodes.Count - 1].X, nodes[nodes.Count - 1].Y)); Robots.GrosRobot.Historique.Log("Chemin optimisé : " + (CheminEnCoursNoeuds.Count - 2) + " noeud(s) intermédiaire(s)", TypeLog.PathFinding); cheminTrouve = true; if (destination.Coordonnees.Distance(new PointReel(finNode.X, finNode.Y)) > 1) { PointsTrouves.Add(new PointReel(destination.Coordonnees)); trajectoire.AjouterPoint(new PointReel(destination.Coordonnees)); } } else { Synchronizer.Unlock(graph); CheminEnCoursNoeuds = null; CheminEnCoursArcs = null; cheminTrouve = false; } } Synchronizer.Lock(graph); graph.CleanNodesArcsAdd(); Synchronizer.Unlock(graph); PointsTrouves = null; ObstacleProbleme = null; ObstacleTeste = null; NodeTrouve = new List<Node>(); CheminTrouve = new List<Arc>(); //Console.WriteLine("PathFinding en " + (DateTime.Now - debut).TotalMilliseconds + " ms"); if (!cheminTrouve) { Robots.GrosRobot.Historique.Log("Chemin non trouvé", TypeLog.PathFinding); return null; } else { if (Plateau.RayonAdversaire < Plateau.RayonAdversaireInitial) { threadRAZRayonAdverse = new Thread(ThreadRAZRayonAdverse); threadRAZRayonAdverse.Start(); } return trajectoire; } }
public static void Dessine() { DateTime prec = DateTime.Now; PositionCurseur = new PointReel(); while (Thread.CurrentThread.IsAlive && !Config.Shutdown) { // Limitation à 30FPS int sleep = 33 - (DateTime.Now - prec).Milliseconds - 1; if (sleep > 0) Thread.Sleep(sleep); prec = DateTime.Now; try { Bitmap bmp = new Bitmap(Properties.Resources.TablePlan.Width, Properties.Resources.TablePlan.Height); { Graphics g = Graphics.FromImage(bmp); g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; if (AfficheTable) DessinePlateau(g); DessineGraph(Robots.GrosRobot, g); //DessineTrajectoire(g); if (Robots.GrosRobot != null) DessineRobot(Robots.GrosRobot, g); if (AfficheHistoriqueCoordonneesGros && Robots.GrosRobot.HistoriqueCoordonnees != null) DessineHistoriqueTrajectoire(Robots.GrosRobot, g); if (AfficheObstacles) DessineObstacles(g); //if (Robots.PetitRobot != null) // DessineRobot(Robots.PetitRobot, g); if (AfficheElementsJeu) DessineElementsJeu(g); DessinePathFinding(g); DessinePositionEnnemis(g); if (AfficheLigneDetections) DessineLignesDetection(g); if (Robots.GrosRobot.PositionCible != null) { Point p = RealToScreenPosition(Robots.GrosRobot.PositionCible); g.DrawEllipse(penRougeEpais, p.X - 5, p.Y - 5, 10, 10); } // Dessin des coûts des mouvements if (Plateau.Enchainement != null) { if (AfficheCoutsMouvementsGros) DessineCoutMouvements(Robots.GrosRobot, g); } if ((modeCourant == Mode.PositionRPCentre || modeCourant == Mode.TeleportRPCentre) && positionDepart != null) { Point positionFin = positionCurseur; Bitmap bmpGrosRobot = new Bitmap(RealToScreenDistance(Robots.GrosRobot.Taille * 3), RealToScreenDistance(Robots.GrosRobot.Taille * 3)); Graphics gGros = Graphics.FromImage(bmpGrosRobot); gGros.FillRectangle(brushTransparent, 0, 0, RealToScreenDistance(Robots.GrosRobot.Taille * 2), RealToScreenDistance(Robots.GrosRobot.Taille * 2)); Direction traj = Maths.GetDirection(positionDepart, PositionCurseurTable); gGros.FillRectangle(brushNoirTresTransparent, bmpGrosRobot.Width / 2 - RealToScreenDistance(Robots.GrosRobot.Largeur / 2), bmpGrosRobot.Height / 2 - RealToScreenDistance(Robots.GrosRobot.Longueur / 2), RealToScreenDistance(Robots.GrosRobot.Largeur), RealToScreenDistance(Robots.GrosRobot.Longueur)); gGros.DrawRectangle(Plateau.NotreCouleur == Plateau.CouleurGaucheViolet ? penCouleurJ1 : penCouleurJ2, bmpGrosRobot.Width / 2 - RealToScreenDistance(Robots.GrosRobot.Largeur / 2), bmpGrosRobot.Height / 2 - RealToScreenDistance(Robots.GrosRobot.Longueur / 2), RealToScreenDistance(Robots.GrosRobot.Largeur), RealToScreenDistance(Robots.GrosRobot.Longueur)); gGros.DrawLine(Plateau.NotreCouleur == Plateau.CouleurGaucheViolet ? penCouleurJ1 : penCouleurJ2, bmpGrosRobot.Width / 2, bmpGrosRobot.Height / 2, bmpGrosRobot.Width / 2, bmpGrosRobot.Height / 2 - RealToScreenDistance(Robots.GrosRobot.Longueur / 2)); Point pointOrigine = RealToScreenPosition(positionDepart); g.DrawImage(RotateImage(bmpGrosRobot, 360 - traj.angle.AngleDegres + 90), pointOrigine.X - bmpGrosRobot.Width / 2, pointOrigine.Y - bmpGrosRobot.Height / 2); g.DrawLine(penBlancFleche, (Point)RealToScreenPosition(positionDepart), positionFin); } else if ((modeCourant == Mode.PositionRPFace || modeCourant == Mode.TeleportRPFace) && positionDepart != null) { Point positionFin = positionCurseur; Bitmap bmpGrosRobot = new Bitmap(RealToScreenDistance(Robots.GrosRobot.Taille * 3), RealToScreenDistance(Robots.GrosRobot.Taille * 3)); Graphics gGros = Graphics.FromImage(bmpGrosRobot); gGros.FillRectangle(brushTransparent, 0, 0, RealToScreenDistance(Robots.GrosRobot.Taille * 2), RealToScreenDistance(Robots.GrosRobot.Taille * 2)); Direction traj = Maths.GetDirection(positionDepart, PositionCurseurTable); Point pointOrigine = RealToScreenPosition(positionDepart); Position departRecule = new Position(360 - traj.angle, pointOrigine); departRecule.Avancer(RealToScreenDistance(-Robots.GrosRobot.Longueur / 2)); gGros.FillRectangle(brushNoirTresTransparent, bmpGrosRobot.Width / 2 - RealToScreenDistance(Robots.GrosRobot.Largeur / 2), bmpGrosRobot.Height / 2 - RealToScreenDistance(Robots.GrosRobot.Longueur / 2), RealToScreenDistance(Robots.GrosRobot.Largeur), RealToScreenDistance(Robots.GrosRobot.Longueur)); gGros.DrawRectangle(Plateau.NotreCouleur == Plateau.CouleurGaucheViolet ? penCouleurJ1 : penCouleurJ2, bmpGrosRobot.Width / 2 - RealToScreenDistance(Robots.GrosRobot.Largeur / 2), bmpGrosRobot.Height / 2 - RealToScreenDistance(Robots.GrosRobot.Longueur / 2), RealToScreenDistance(Robots.GrosRobot.Largeur), RealToScreenDistance(Robots.GrosRobot.Longueur)); gGros.DrawLine(Plateau.NotreCouleur == Plateau.CouleurGaucheViolet ? penCouleurJ1 : penCouleurJ2, bmpGrosRobot.Width / 2, bmpGrosRobot.Height / 2, bmpGrosRobot.Width / 2, bmpGrosRobot.Height / 2 - RealToScreenDistance(Robots.GrosRobot.Longueur / 2)); g.DrawImage(RotateImage(bmpGrosRobot, 360 - traj.angle.AngleDegres + 90), (int)(departRecule.Coordonnees.X) - bmpGrosRobot.Width / 2, (int)(departRecule.Coordonnees.Y) - bmpGrosRobot.Height / 2); g.DrawLine(penBlancFleche, (Point)RealToScreenPosition(positionDepart), positionFin); } // Trajectoires foreach (Trajectoire traj in Trajectoires) { DessineTrajectoire(traj, g); } if (Robots.GrosRobot.TrajectoireEnCours != null) { Trajectoire traj = new Trajectoire(); traj.AjouterPoint(Robots.GrosRobot.Position.Coordonnees); for (int iPoint = 1; iPoint < Robots.GrosRobot.TrajectoireEnCours.PointsPassage.Count; iPoint++) traj.AjouterPoint(Robots.GrosRobot.TrajectoireEnCours.PointsPassage[iPoint]); DessineTrajectoire(traj, g); } // Trajectoire polaire //if (modeCourant == Mode.TrajectoirePolaire) { if (trajectoirePolaireScreen !=null) foreach (Point p in trajectoirePolaireScreen) g.FillEllipse(Brushes.Red, p.X - 1, p.Y - 1, 2, 2); if (pointsPolaireScreen != null) foreach (Point p in pointsPolaireScreen) g.DrawEllipse(Pens.Black, p.X - 3, p.Y - 3, 6, 6); } TableDessinee(bmp); } } catch (Exception ex) { Console.WriteLine("Erreur pendant le dessin de la table " + ex.Message); } } }