Application à la collision Box / Plan
Une fois le point d’intersection trouvé, il suffit d’appliquer ces formules pour calculer l’impulsion, en considérant que le plan n’a ni vitesse linéaire, ni vitesse angulaire. De plus on considère sa masse comme étant infinie et de même pour son moment d’inertie.
Les résultats obtenus avec ce calcul de l’impulsion sont très satisfaisants. Nous avions commencé cette implémentation pour la collision Box/Plan mais comme ce calcul est totalement générique, nous l’avons appliqué pour tous les autres types de collision. Cependant, à cause d’un manque de temps, nous n’avons pas modifiés les méthodes de gestion d’intersection que nous avions déjà implémentées.
Recalage au point de collision.
Pour le cas de la collision Boite/Plan, nous allons devoir « remonter dans le temps » pour retrouver le moment ou la boîte avait exactement un seul point de contact avec le plan. Une difficulté supplémentaire apparaît alors : non seulement la boîte s'est translatée, mais elle a également tourné en même temps.
Mise en équation du problème
On appelle « d » la distance du centre de la boite au plan. d0 est la distance initiale.
· représente les coordonnées du point de contact dans le repère local de la boîte.
· θ0 représente l'angle initial entre le point de contact et la normale et θ mesure la variation de cette angle au cours du temps.
On a dans le triangle colorié en bleu :
Plus généralement lorsqu'on « remonte dans le temps », on a :
Or, et θ=ω.Δt avec ω vitesse angulaire de la boîte. Donc,
On cherche alors à trouver le Δt.
Méthodes de résolution
Notre équation nous ramène donc à chercher le point d'intersection entre un cosinus et une droite, en effet notre équation peut se mettre sous la forme cos( ω.Δt +θ0 )=aΔt +b avec a,b, ω et θ0 positifs.
Pour résoudre cette équation nous avons pensé à deux possibilités:
-
Développement limité du cosinus
En réalisant un développement limité du cosinus nous nous ramerons à une équation du second degré et nous pourront ainsi en tirer une expression analytique pour Δt:
Cependant le développement limité n'est valable qu'au voisinage de 0, on risque alors d'avoir une imprécision sur Δt dès que l'angle formé par θ+θ0 devient grand.
-
Dichotomie
C'est la méthode que nous avons choisi d'implémenter. Nous avons remarqué que l'angle θ+θ0 est compris entre 0 et pi/2. On a donc une première indication sur un intervalle dans lequel nous pourront trouver Δt : 0 < Δt < (pi/2-θ0)/ω. Ceci constituera notre intervalle de départ pour la dichotomie. De plus, on peut donc en déduire que le cosinus de θ+θ0 sera décroissant sur l'intervalle considéré et sera compris entre 0 et cos(θ0).
Or a et b sont positif, donc la droite elle est croissante. De plus, en Δt=0 le membre de gauche vaut cos(θ0) et le membre de droite vaut b.
Or et avec donc .
Il y a donc bien une solution et une seule à notre problème.
On va alors pouvoir procéder à la recherche de Δt par dichotomie en évaluant, et en rétrécissant l'intervalle par le bas si la quantité est positive et par le haut si elle est négative. On a estimé qu'en 10 itérations nous avions une bonne estimation de Δt.
Connaissant Δt, par l'une ou l'autre des méthodes, on peut alors recaler notre boîte sans difficulté.
La collision Box / Sphère
Détection de la collision
La détection est faite en utilisant tout ce qui a été vu précédemment. On calcule les contributions des axes du cube par projection sur l’axe liant les deux centres de gravité des objets.
Soient une boîte
, de centre
, de dimensions
suivant les axes de son repère local
et une sphère
de centre
et de rayon
.
Une étape supplémentaire est nécessaire ici pour se servir correctement du calcul de l’impulsion. Il s’agit de calculer la normale au point de collision. En effet, deux cas de figures sont possibles :
-
La collision se produit sur la face du cube. Dans ce cas, la normale de collision est égale à la normale de la face du cube.
-
La collision a lieu sur un sommet du cube. Dans ce cas, la normale de collision est égale au vecteur
normalisé.
On pose
. Ensuite on a toujours
. La condition de la collision est alors :
Gestion de la collision
Nous calculons l’impulsion en considérant que la sphère n’a pas de vitesse angulaire et que le moment d’inertie est infini.
Collision Boîte / Boîte
Détection de la collision Boîte / Boîte
Pour détecter une collision entre deux boîtes, on s'appuie sur le théorème de l'axe séparateur. Si deux boîtes ne sont pas en contact alors il existe un axe séparateur , où et sont des vecteurs disjoints choisis parmi les 6 axes des boîtes.
Un axe est dit séparateur s’il existe un plan orthogonal à celui-ci qui sépare les deux boîtes et que cet axe soit orthogonal à la face d'une des deux boîtes ou orthogonal à deux cotés de chaque boite.
Ceci conduit à tester les 15 axes suivants :
1.
Collision face avec un sommet
- Normale face1 objet 1
- Normale face2 objet 1
- Normale face3 objet 1
- Normale face1 objet 2
- Normale face2 objet 2
- Normale face3 objet 2
2.
Collision arrête avec une autre arrête
- Normale face1 objet1 ^ Normale face1 objet2
- Normale face1 objet1 ^ Normale face2 objet2
- Normale face1 objet1 ^ Normale face3 objet2
- Normale face2 objet1 ^ Normale face1 objet2
- Normale face2 objet1 ^ Normale face2 objet2
- Normale face2 objet1 ^ Normale face3 objet2
- Normale face3 objet1 ^ Normale face1 objet2
- Normale face3 objet1 ^ Normale face2 objet2
- Normale face3 objet1 ^ Normale face3 objet2
Le test s'effectue simplement par projection des boîtes sur les axes:
Ainsi on peut montrer que L est un axe séparateur s'il satisfait la condition suivante:
, avec et les dimensions des cubes.
L'algorithme s'arrête dès la détection du premier axe, séparateur il n'y a alors pas de collision. Si pour aucun des 15 axes cette condition n'est vérifiée alors il y a collision.
Gestion de la collision Boîte / Boîte
Nous utilisons la technique décrite dans le chapitre Gestion de la collision Boîte / Plan, généralisée à deux objets.
La normale de la collision est alors définie comme étant l'axe séparateur trouvé précédemment.
Pour trouver les coordonnées du point de contact nous séparons les cas :
- Collision entre un sommet et une face
- Collision entre deux arrêtes
Collision sommet/face:
On cherche le sommet de la boite en collision, pour cela on se base sur le produit scalaire entre les axes de cette boite et la normale:
avec
orienté vers la boîte dont le sommet est en collision.
PointContact = PointContact + PositionBoite //Conversion des coordonnées locales en coordonnées globales
Implémentation collision sommet / face
Collision arrête/arrête:
De la même manière on va chercher le point de contact dans le repère locale d'une des boites puis le convertir en coordonnées globales. Par définition la normale est orthogonale à un des axes de la boite. Pour les deux autres axes on procédera de la même manière que précédemment.
If (
== 0)
avec
orienté vers la boite dont le sommet est en collision.
else
//avec P vecteur liant le centre des deux boites
endif
// ----------------------------------------------------------------------------------------
If ( == 0)
else
endif
// ----------------------------------------------------------------------------------------
If ( == 0)
else
endif
// ----------------------------------------------------------------------------------------
PointContact = PointContact + PositionBoite //Conversion des coordonnées locales en coordonnées globales
Implémentation collision arrête / arrête
Recalage au point de collision
Nous n'avons pas souhaité implémenter ce recalage par manque de temps.