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.
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).
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;
}
}
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
"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é.
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).
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.
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 ?
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.
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).
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.
Ctrl+space
Ctrl+space
Ctrl+space
Ctrl+space
Ctrl+space