Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Processing] probleme de collision balle/ligne

Sujet résolu
    15 avril 2015 à 20:23:04

    Bonjour, depuis un petit moment moi et mon collègue bloquons sur un problème :

    Une balle rebondi dans un espace qui lui est donné et avec la souris on peut tracer une ligne. La balle est censé rebondir dessus mais quelque fois la balle ce coince quand elle passe dans la ligne et la condition du rebondissement ce renouvelle a l'infinie. J'aurais bien voulu coller le code ici mais il est fait en plusieurs parties du coup je préfère vous envoyer le dossier si vous voulez y jeter un œil (et m'aider en meme temps ;) ) .

     Quelques images en guise d'exemple : 

    La photo ci dessus montre la balle avançant en direction de la ligne verte.

    Et cette photo montre lorsque la balle bloque dans la ligne.

    J'ai retiré le lien contenant mon projet.

    J'espere pouvoir etre aider !! A bientot :)

    -
    Edité par Alias95 26 avril 2015 à 20:30:30

    • Partager sur Facebook
    • Partager sur Twitter
      20 avril 2015 à 14:18:19

      Poste juste la partie qui correspond au rebondissement. Essaye d'expliquer ce que font les différentes fonctions. Ce sera plus simple pour t'aider (surtout que je n'ai pas de quoi décompresser les rar>_<).
      • Partager sur Facebook
      • Partager sur Twitter

      Ctrl+space

        25 avril 2015 à 15:21:06

        Désolé du retard j'était en vacances :).

        Voila la partie du code où il y a le problème :

        boolean collision(int d, float lx1, float ly1, float lx2, float ly2, float bx, float by) {
          // first get the length of the line using the Pythagorean theorem
          float distX = lx1-lx2;
          float distY = ly1-ly2;
          float lineLength = sqrt(pow(distX,2) + pow(distY,2));
        
          // then solve for r
          float r = (((bx-lx1)*(lx2-lx1))+((by-ly1)*(ly2-ly1)))/pow(lineLength, 2);
        
          // get x,y points of the closest point
          float closestX = lx1 + r*(lx2-lx1);
          float closestY = ly1 + r*(ly2-ly1);
          
        
          // to get the length of the line, use the Pythagorean theorem again
          float distToPointX = closestX - bx;
          float distToPointY = closestY - by;
          normale = new PVector(distToPointX, distToPointY);
          float distToPoint = sqrt(pow(distToPointX, 2) + pow(distToPointY, 2));
        
          // for explanation purposes, draw a line to the ball from the closest point
          strokeWeight(1);
          stroke(255, 0, 0);
          line(closestX, closestY, bx, by);
          stroke(0, 128, 0);
          line(bx, by, bx+vitesse.x*100, by+vitesse.y*100);
          strokeWeight(3);
          float a = PVector.angleBetween(vitesse, normale);
          //println(degrees(a));
        
          // if that distance is less than the radius of the ball: collision
          if (distToPoint <= d/2 && ((position.x> lx1 && position.x<lx2) || (position.x< lx1 && position.x>lx2))) {
            vitesse.rotate(PI-2*a);
            return true;
          } 
          else {
            return false;
          }
        }
        
        C'est tout en bas à ce niveau :
        if (distToPoint <= d/2 && ((position.x> lx1 && position.x<lx2) || (position.x< lx1 && position.x>lx2)))
         en gros la condition se répète à l'infinie quand la distance entre la balle et la droite est inférieur ou égal au rayon de la balle. Je sais pas comment régler ce problème sa fait 3 semaines qu'on plante dessus :D

         "distToPoint" est la variable qui donne la distance entre le centre de la balle et la droite.

        le vecteur "normale" est la normale de la droite tracé. 

        ((position.x> lx1 && position.x<lx2) || (position.x< lx1 && position.x>lx2))

        ce morceau de code dans la condition sert à faire en sorte que la balle rebondisse seulement sur ce qu'on a tracé (sur le segment et non pas la droite infinie).

        -
        Edité par Alias95 25 avril 2015 à 15:29:00

        • Partager sur Facebook
        • Partager sur Twitter
          25 avril 2015 à 17:29:15

          Bon j'ai peut être un moyen: si j'ai bien compris tu as les coordonnées de closest qui est en fait le point d'intersection entre la droite perpendiculaire au segment(mur) passant par le centre de la balle et le segment. Ce que je propose c'est de vérifier que la direction de la balle soit bien vers le mur.

          AB est le mur. D  est le point que tu as appelé closest. Et C est le centre de la balle.


          Ce que je pensais faire c'est comme sur ce schéma tu prend le vecteur v que tu obtient grâce à ta vitesse v(vitesse.x;vitesse.y) tu obtient donc un point F translation de C par v. Tu prend ensuite le point F, intersection de la droite CD et de la perpendiculaire à CD passant par F que tu trouve via la définition de l'équation de (CD) demande moi si tu ne sais pas comment faire. Ensuite tu n'as plus qu'à comparer le sens des vecteurs CD et CF en regardant si CD.x et CF.x ou/et CD.y et CF.y ont le même signe. Si oui, tu rebondis, si non tu ne rebondis pas.

          Cas particuliers Si CD est horizontale ou verticale tu vas te retrouver avec des divisions par zéro lors du calculs des équations.

          -
          Edité par zero857 26 avril 2015 à 21:18:59

          • Partager sur Facebook
          • Partager sur Twitter

          Ctrl+space

            26 avril 2015 à 0:01:15

            Ouuii j'ai compris le principe, par contre pour la definition de l'equation de la droite (CD) je ne vois comment faire, tu peux me dire comment faire ?

            Merci.

            • Partager sur Facebook
            • Partager sur Twitter
              26 avril 2015 à 10:21:31

              Donc l'équation d'une droite prend la forme y= mx+ p

              Pour la calculer à partir de 2 points C(xc;yc) et D(xd;yd) ln fait comme ça :

              On cherche m, le coefficientdirecteur: m=(yd-yc)/(xd-xc) attention à l'ordre des termes et à la division par 0!

              On trouve p comme ça : yc=m*xc+p donc p=yc - (m*xc)

              Ensuite pour trouver la perpendiculaire tu fait une nouvelle équation de droite: y= m'*x+p' sachant que m'=(-1)/m attention aux divisions par 0!

              Pour p' tu le trouve comme p mais en utilisant m' et les coordonnées de E.

              • Partager sur Facebook
              • Partager sur Twitter

              Ctrl+space

                26 avril 2015 à 11:52:12

                Une autre solution est d'associer à chaque mur un identifiant unique et de stocker l'identifiant du dernier mur sur lequel la balle a rebondis. Il faut ensuite vérifier que la balle ne rebondis pas deux fois d'affilée sur un même mur.

                Les deux méthodes devraient fonctionner à toi de choisir celle qui t'arrange le plus.

                -
                Edité par zero857 26 avril 2015 à 11:52:38

                • Partager sur Facebook
                • Partager sur Twitter

                Ctrl+space

                  26 avril 2015 à 20:29:35

                  Merci beaucoup tu m'aides vraiment ! Je vais voir la quelle de tes 2 méthodes est la plus simple. Merci :D
                  • Partager sur Facebook
                  • Partager sur Twitter
                    26 avril 2015 à 21:18:25

                    La 2nd méthode implique par contre des petites modifications (pas grand chose mais il faut faire attention) si jamais tu veut que la balle revienne si elle sort des limites (style pacman).
                    • Partager sur Facebook
                    • Partager sur Twitter

                    Ctrl+space

                    [Processing] probleme de collision balle/ligne

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown