Exemple #1
0
        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;
        }
Exemple #2
0
        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;
        }
Exemple #3
0
        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));
                }
            }
        }
Exemple #4
0
        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;
            }
        }
Exemple #5
0
        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);
                }
            }
        }