67 votes

Comment calculer l'angle de rebond ?

J'ai joué avec pendant un moment, mais je n'arrive pas à comprendre.

J'ai créé un tank qui tire des missiles, et quand les missiles frappent les murs, je veux qu'ils rebondissent, mais je veux qu'ils rebondissent dans le bon angle.

Pour l'instant, je n'ai pas d'obstacles, les missiles rebondissent lorsqu'ils sortent du champ de tir. viewportRectangle J'ai fait.

La solution que je recherche est-elle assez avancée ?

Existe-t-il un moyen relativement simple de le faire ?

2 votes

Il s'agit d'un problème dont la solution deviendrait probablement immédiatement évidente si vous alliez faire une partie de billard.

200voto

Gareth Rees Points 31350

Vous pourriez penser que, puisque vos murs sont alignés avec les axes de coordonnées, il est logique d'écrire un code spécial (pour un mur vertical, annulez la coordonnée x de la vitesse ; pour un mur horizontal, annulez la coordonnée y de la vitesse). Cependant, une fois que vous avez réussi à faire fonctionner le jeu avec des murs verticaux et horizontaux, la prochaine chose à laquelle vous penserez probablement est "qu'en est-il des murs à angles arbitraires ?". Il vaut donc la peine de penser au cas général dès le début.

Dans le cas général, supposez que votre missile a une vitesse v et frappe un mur dont la normale à la surface est n .

Missile with vector v about to obliquely hit a wall with surface normal n.

Split v en composants u perpendiculaire à la paroi et w parallèle à celle-ci.

Right-angled triangle with hypotenuse for v, short side u parallel to wall and long side w parallel to wall.

Où :

u \= ( v  -  n / n  -  n ) n
w \= v u

Ici, v  -  n est le produit scalaire des vecteurs v y n . Voir le lien pour une explication sur la façon de le calculer. Le produit scalaire n  -  n est évalué au carré de la longueur du vecteur normal ; si vous gardez toujours vos normales sous la forme de vecteurs unitaires puis n  -  n \= 1 et vous pouvez omettre la division.

Après le rebond, la composante du mouvement parallèle au mur est affectée par la friction. f et la composante perpendiculaire à la paroi est affectée par l'élasticité, qui peut être donnée sous la forme de a coefficient de restitution r .

Donc la vitesse après la collision est de v \= f w r u . Dans une collision parfaitement élastique et sans frottement, v \= w u c'est-à-dire que le mouvement est réfléchi autour de la normale au point de collision, comme dans le schéma donné dans la réponse de Bill.

Cette approche fonctionne de la même manière en trois dimensions.

(Il s'agit évidemment d'une notion très simplifiée du rebondissement ; elle ne tient pas compte du moment angulaire ou de la déformation. Mais pour de nombreux types de jeux vidéo, ce type de simplification est parfaitement adéquat).

3 votes

Je suis d'accord pour dire que commencer par le codage de cas spéciaux pour les murs verticaux et horizontaux n'est pas la bonne façon de procéder. Il ne s'agit pas d'un tremplin vers la bonne voie, mais plutôt d'une voie sans issue.

0 votes

Hé les gars, c'est une explication géniale, mais je pense qu'il y a un bug. Cela ne devrait-il pas être u = -n ( v.n / n.n ) ? Après tout, u est dans la direction inversée de n.

1 votes

Suis-je le seul à être confus avec l'utilisation de v.n, au lieu d'utiliser v-n ? Quand j'ai lu n.n, mon cerveau a explosé, pensant qu'un normal avait un élément appelé normal. (je suis trop habitué à c++ ?).

71voto

Bill the Lizard Points 147311

Je pense qu'un moyen plus facile de le faire est d'utiliser la vitesse du missile au lieu de calculer les angles. Disons que vous avez un missile qui a xVelocity y yVelocity pour représenter son mouvement horizontal et vertical. Ces vitesses peuvent être positives ou négatives pour représenter la gauche, la droite, le haut ou le bas.

  • Si un missile frappe une bordure supérieure ou inférieure, inversez le signe du yVelocity .
  • Si un missile frappe une frontière gauche ou droite, inversez le signe du xVelocity .

Ainsi, le mouvement dans l'axe opposé restera le même.

En empruntant l'image de La réponse de ChrisF disons que le missile commence à la position I.

Angle of Reflection

Avec le xVelocity y yVelocity étant tous deux positifs (dans les graphiques 2D, la droite et le bas sont généralement positifs), le missile se déplace dans la direction indiquée. Attribuons simplement les valeurs de

xVelocity = 3
yVelocity = 4

Lorsque le missile frappe le mur à la position C son xVelocity ne devrait pas changer, mais son yVelocity doit être inversé à -4 pour qu'il revienne dans le sens de la montée, mais continue à aller vers la droite.

L'avantage de cette méthode est que vous n'avez qu'à suivre l'évolution du missile. xPosition , yPosition , xVelocity y yVelocity . Avec ces quatre composants et la fréquence de mise à jour de votre jeu, le missile sera toujours redessiné à la bonne position. Lorsque vous rencontrerez des obstacles plus complexes, qui ne sont pas à angle droit ou qui se déplacent, il sera beaucoup plus facile de travailler avec les vitesses X et Y qu'avec les angles.

0 votes

J'utilise l'angle du missile pour le faire avancer, en utilisant Math.Sin et Math.Cos. J'ai eu du mal à comprendre l'autre méthode, qui consiste à utiliser la vitesse, comme dans l'exemple XNA avec les boules de canon. Il suffit donc de modifier l'angle du missile pour qu'il avance tout seul.

0 votes

De la bonne physique. Une TRES belle illustration. +1 juste pour ça, puisqu'une image vaut 10K mots. Je distribue des micropoints, donc c'est 0,001 par mot gagné. 8)

32 votes

Cela ne fonctionne que si tous vos murs sont alignés sur les axes de coordonnées, et même dans ce cas, il faut des cas séparés pour les murs verticaux et horizontaux. Il est probablement plus facile de faire les choses correctement dans le cas général.

8voto

ChrisF Points 74295

Pour les particules parfaites (et la lumière), l'angle de réflexion est égal à l'angle d'incidence, comme l'illustre ce diagramme (tiré de commons.wikimedia.org).

Angle of Reflection

El Page Wikipedia sur la réflexion explique très bien comment cela fonctionne.

C'est un peu plus compliqué lorsque l'on prend en compte l'élasticité et les matériaux de l'objet et des obstacles, mais c'est probablement suffisant pour la plupart des applications.

6voto

itsmatt Points 18905

En marge de la question de physique que vous posez, je vous recommande le livre "Beginning Math and Physics for Game Programmers" de Wendy Stahler. Je l'ai trouvé très utile pour mes projets de programmation de jeux/physique.

Le code qui accompagne le livre est en C++ mais si vous connaissez le C#, il serait assez facile de faire la conversion.

Passez une bonne journée !

2voto

Yuval Adam Points 59423

Pas compliqué du tout - pseudo-code :

angleObjectHitWall = a;
bounceAngle = 180-a;

Bien sûr, il s'agit d'un calcul très simple, qui n'est absolument pas pertinent dès lors que l'on commence à prendre en compte des facteurs tels que le matériau, la gravité, les murs qui ne sont pas droits, etc...

4 votes

Non. Cela ne fonctionne que dans le cas où l'angle d'incidence et de réflexion est le même.

0 votes

@bergin - ce qui, pour les particules idéalisées dans les jeux, est presque toujours le cas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X