December 20, 2016
La détection de collision entre objets est un problème récurrent dans les jeux vidéos. En 2D une comparaison de chaque pixels formant l’objet à détecter devient très couteux en termes de performance dès lors que le nombre de pixels croît ou que le nombre de collisions à détecter augmente.
Une autre approche consiste donc à utiliser une forme simple couvrant l’objet, qui permettra une détection plus efficace. Une des formes les plus simples de détection de collision est une collision entre deux cercles. En effet, il suffit de vérifier que la distance entre le centre des deux cercles soit inférieure à la somme de leur rayon pour détecter la collision. De même, le rectangle est un conteneur permettant la détection de collision en temps constant. Ces formes simples nous permettent d’obtenir des détections de collision approximatives mais avec de bonnes performances. Le polygone convexe est un meilleur conteneur dans le sens où il permet de couvrir l’objet de façon plus précise mais la détection de collision est plus complexe. En effet si nous avons deux polygones avec respectivement et cotés, alors la détection de collision entre ces deux polygones s’exécute en
Notre problématique est d’analyser la qualité de conteneurs d’un ensemble de points dans le plan. Dans cet objectif, nous étudierons 2 algorithmes distincts :
L’algorithme Toussaint permet d’obtenir un rectangle d’aire minimum contenant un ensemble de points.
Propriété : Le rectangle minimum contenant un ensemble de points a un côté parallèle avec l’un des côtés de l’enveloppe convexe de ces points.
Cet algorithme se décompose en 7 grandes étapes :
Etape 0 : Nous obtenons l’enveloppe convexe en appliquant l’algorithme Graham sur l’ensemble des points en . Cet algorithme nécessite un pré-calcul, appelé trie pixel dans lequel nous parcourons une fois l’ensemble de points. De plus nous parcourons chaque triplet de points successifs pour déterminer l’enveloppe convexe.
Complexité :
Etape 1 : L’obtention des points d’abscisse minimum et maximum se fait en . De même pour les points d’ordonnée minimum et maximum.
Etapes 2, 3, 4, 5, 6 : Ici nous avons affaire à de simples constructions effectuées en temps constant.
Etape 7 : Les opérations sont répétées pour chaque côté de l’enveloppe convexe — dans le pire cas nous avons cotés. Complexité :
L’algorithme Toussaint possède donc une complexité de .
Nous définissons une droite par un point et un vecteur directeur.
Soit une droite définie par un point et un vecteur . Soit une seconde droite définie par un point et un vecteur .
Les deux lignes se coupent si nous pouvons trouver un point tel que :
Equation de t :
Comme
Ainsi nous avons
et le point d’intersection est
Source: stackoverflow
Les coordonnées du polygone convexe sont rangées dans le déterminant ci dessous.
Dans notre implémentation, les droites sont représentées par un point et un vecteur directeur. La rotation d’une droite affecte la direction de son vecteur directeur. On applique donc la formule de rotations vectorielles définie ci dessous :
Ainsi on obtient :
Une petite remarque, lors de l’implémentation de l’algorithme Toussaint, il est arrivé que l’on ait à effectuer une rotation d’une droite d’un angle très petit ( inférieur à ) Dans ce cas là on considère que l’angle vaut 0.
Source: wikipedia
L’algorithme Ritter permet d’obtenir un cercle d’aire minimum contenant un ensemble de points.
On obtient le point C’ via les coordonnées barycentriques tel que : avec
et
Les étapes 1, 4, 5, 7, 8, 9 et 10 sont effectuées en temps constant → . On parcourt aux étapes 2, 3 et 6 tous les points → Enfin à l’étape 11 on répète 6-10 un nombre limité de fois → complexité totale
L’algorithme Ritter possède donc une complexité de .
Intéressons-nous à l’évolution du temps d’exécution de chacun des algorithmes en fonction du nombre de points. Nous faisons croitre ce nombre de 256 à 425984.
On voit clairement que le temps d’exécution des algorithmes Toussaint et Ritter augmente de façon linéaire en fonction du nombre de points. On note également un coefficient directeur de droite plus élevé pour le second ce qui, somme toute, confirme leur complexité théorique respective de et
Notre base de test contient 1664 instances de tests contenant chacune 256 points dans un plan 2D. Pour chaque instance on s’intéresse à la qualité du conteneur selon la formule :
Plus la valeur obtenue est petite, plus l’aire du conteneur est proche de celle de l’enveloppe convexe — et donc la valeur la plus petite est la meilleure.
On constate que Ritter est très légèrement meilleur que Toussaint sur la majorité des instances. La qualité moyenne obtenue par l’algorithme Toussaint est de ce qui indique un rectangle d’aire en moyenne plus grande que celle de l’enveloppe convexe. L’algorithme Ritter, lui, nous donne une moyenne de → aire du cercle en moyenne plus grande que celle de l’enveloppe convexe.
Aussi, il est bon de remarquer l’écart entre la valeur minimum et maximum du cercle Ritter. Cela s’explique par la forme du polygone.
Lorsque le polygone possède une hauteur très différente de sa largeur (figure a) alors le cercle Ritter perd en qualité, il possède une aire bien plus grande que celle du polygone. Dans ce cas, le rectangle obtenu avec Toussaint est meilleur en termes de qualité. À l’inverse, plus la forme du polygone tend vers celle d’un polygone régulier (figure b) et plus le cercle Ritter sera de bonne qualité, son aire sera proche de celle du polygone.
Les deux algorithmes offrent des conteneurs de qualité sensiblement identiques. Si le nombre de points est de l’ordre de alors on ne note pas de différence majeure en termes de temps d’exécution. Au-delà de points on préfèrera utiliser l’algorithme Toussaint qui aura un meilleur temps d’exécution.