Licence Informatique 2017-2018
II2D



TP 03 : Collision

Objectifs :

1  Préparation

Question 1. Pour gérer la collision, il faut, pour une particule donnée, connaitre son ancienne position et son ancienne vitesse (les x_old et v_old du cours). Pour l’instant, vous perdez ces informations dès que vous mettez à jour la position et la vitesse avec la résolution du mouvement (cf la méthode Engine.motion du tp précédent). On propose de mémoriser ces informations directement dans la classe Particle : faire des attributs oldPosition et oldVelocity (par exemple) dans la classe Particle. Assurez-vous alors de les mettre à jour lors du calcul du mouvement dans Engine.motion.

Question 2. Faire un nouveau fichier ii2d_obstacle.js dans lequel vous intégrez la classe Circle (attributs centre et radius initialisés dans le constructeur).

Question 3. Intégrez également une classe ObstacleManager pour recevoir une liste d’obstacles (inspirez vous de ParticleManager pour le constructeur : il suffit de créer une liste vide). Créez alors un ObstacleManager dans le constructeur de Engine (identique à la création du ParticleManager).

Question 4. Intégrez :

  1. l’affichage d’un cercle : il faut passer par un beginPath en utilisant arc; voir un exemple ici sur le MDN
  2. l’affichage de l’ensemble des obstacles (faire une méthode draw dans ObstacleManager : boucle sur tous les obstacles)
  3. et, enfin, testez le tout (par exemple dans le main créez 2 obstacles Circle en les ajoutant au ObstacleManager de engine; n’oubliez pas d’appeler le draw de l’ObstacleManager depuis le Engine.draw).

La vidéo qui suit est issue de la création de 2 obstacles dans la méthode main par :

var obs1=new Circle(new Vector(100,100),50); var obs2=new Circle(new Vector(250,200),20); engine.obstacleManager.all.push(obs1,obs2);

2  Détection (cercle)

Question 5. On propose la décomposition générale. Faites une méthode Engine.collision() qui parcourt toutes les particules, et pour chaque particule parcourt tous les obstacles en appelant une méthode Engine.solveCollision(une_particule,un_obstacle) (qui ne fait rien pour l’instant). N’oubliez pas d’appeler collision() dans le Engine.updateData pour provoquer la résolution des collisions.

On se concentre à présent sur solveCollision(une_particule, un_obstacle).

Question 6. Il faut détecter s’il y a collision avec un cercle : faites une méthode Cercle.intersect(p1,p2)[p1,p2] correspond au segment de la trajectoire à tester (i.e. qui correspondront donc aux 2 extrémités x_old et x_new pour notre application). Cette méthode doit donner 3 résultats : elle indique s’il y a intersection ou non avec le segment [p1,p2], et, le cas échéant, la normale à l’intersection et la position de l’intersection (cf cours). Pour retourner un résultat multiple en Javascript, vous pouvez faire quelque chose qui ressemble à return {isIntersect : false, normal : new Vector(1,0), position : new Vector(1,1)} (exemples de valeurs : il faut les calculer correctement).

Pour tester, appelez alors cette méthode depuis Engine.solveCollision(une_particule,un_obstacle) : selon le résultat, affectez la position de une_particule à son ancienne position (il s’agit juste de vérifier visuellement si la détection est correcte en "immobilisant" la particule en la ramenant à son ancienne position).

3  Réponse à la collision

Il faut modifier la position et la vitesse de la particule pour traduire le principe d’impulsion.

Question 7. Depuis solveCollision appelez (quand il y a collision) une méthode impulse(p,ncol,pcol)p est la particule, ncol la normale au point de collision et pcol le point de collision. Modifiez alors p.position et p.velocity :

  1. Calculer la vitesse normale (nécessite le produit scalaire pour Vector) : affectez alors la vitesse de la particule avec la vitesse corrigée (cf cours; prenez un coefficient de restitution à 1 pour l’instant)
  2. Calculer la correction en position (cf cours).

Testez

Question 8. Vous disposez à présent du coeur de votre projet et constitue le strict minimum. La suite, dans le prochain sujet de tp, constitue des enrichissements.


Ce document a été traduit de LATEX par HEVEA