Réponse aux collisions de jeux 2D: SAT et déplacement minimum le long d'un axe donné?

13

J'essaie d'implémenter un système de collision dans un jeu 2D que je fais. Le théorème de l'axe de séparation (tel que décrit par le didacticiel sur les collisions de metanet ) semble être un moyen efficace et robuste de gérer la détection des collisions, mais je n'aime pas vraiment la méthode de réponse aux collisions qu'ils utilisent. En se déplaçant aveuglément le long de l'axe du moindre chevauchement, l'algorithme ignore simplement la position précédente de l'objet en mouvement, ce qui signifie qu'il n'entre pas en collision avec l'objet stationnaire autant qu'il y entre et rebondit ensuite.

Voici un exemple de situation où cela aurait de l'importance:

Exemple

Selon la méthode SAT décrite ci-dessus, le rectangle sortirait simplement du triangle perpendiculaire à son hypoténuse:

Réponse de style SAT

Cependant, de manière réaliste, le rectangle devrait s'arrêter dans le coin inférieur droit du triangle, car ce serait le point de première collision s'il se déplaçait continuellement le long de son vecteur de déplacement:

Réponse réaliste

Maintenant, cela n'a peut-être pas vraiment d'importance pendant le jeu, mais j'aimerais savoir s'il existe un moyen d'atteindre efficacement et généralement des déplacements précis de cette manière. J'en ai creusé la tête ces derniers jours et je ne veux pas encore abandonner!

(Post-cross de StackOverflow, j'espère que ce n'est pas contraire aux règles!)

Archagon
la source
C'est contraire aux règles. Ne croisez pas.
AttackingHobo
Oui, supprimez-le de StackOverflow et conservez-le ici: P
TravisG
gamedev.stackexchange.com/questions/9144/… J'ai répondu à votre question particulière ici.
ultifinitus
Supprimé de SO.
Archagon
Lancer une prime, archagon: P Sinon, je pourrais avoir à le faire. Cette question est vraiment intéressante, et ce serait génial de voir une réponse qui fait plus que simplement énumérer quelques références.
TravisG

Réponses:

11

Voici la méthode que j'ai trouvée. Il pourrait être défectueux, mais je n'ai pas encore trouvé de problème avec cela dans mon analyse superficielle. Il fonctionne également pour les polygones arbitraires avec quelques modifications mineures.

Dans les illustrations ci-dessous, l'objet bleu se déplace et l'objet rouge est immobile. 1 Étape 1: Pour chaque polygone, trouvez les deux points les plus éloignés le long de la projection de ce polygone sur la ligne perpendiculaire au vecteur de mouvement. 2 Étape 2: Divisez chaque polygone le long de la ligne reliant ces points. La moitié du polygone qui fait face à l'autre polygone le long du vecteur de mouvement est la "coque avant". C'est la seule partie du polygone qui peut éventuellement entrer en collision. 3 Étape 3:Projetez un vecteur à partir de chaque point sur la "coque avant" de chaque polygone le long du vecteur de mouvement vers le polygone opposé, et vérifiez-le pour l'intersection avec chaque bord de la "coque avant" du polygone opposé. (Peut-être lent, mais les ordinateurs sont assez rapides de nos jours - non?) (Désolé pour la flèche inclinée. Toutes les flèches devraient être parallèles.) 4 Étape 4: Prenez le vecteur le plus court. Il s'agit de la distance de collision exacte. 5 Étape 5: Voila! 6

Archagon
la source
2
C'est assez impressionnant. Avez-vous par hasard comparé la vitesse de votre algorithme à un multi-échantillonnage simple (4x ou 8x)?
TravisG
Malheureusement non.
Archagon
Impressionnant, et je suis sûr que les mathématiques ne sont pas trop compliquées / intensives non plus. +1
you786
7

Découvrez cette question similaire: Résolution de collision

Et aussi, depuis http://www.metanetsoftware.com/technique/tutorialA.html#section5 (auquel vous avez posté un lien vers :))

SECTION 5: Objets se déplaçant rapidement

Comme mentionné ci-dessus, les petits objets et / ou les mouvements rapides peuvent produire des problèmes lors de l'utilisation d'un test de collision statique. Il existe plusieurs approches qui peuvent être prises pour gérer de tels objets - la plus simple est de contraindre la conception de votre jeu afin que ces objets ne soient pas nécessaires.

Si vous en avez absolument besoin, il existe deux méthodes courantes pour traiter les petits objets et / ou les objets en mouvement rapide: les tests de collision par balayage et le multi-échantillonnage.

- = tests de balayage = -

Au lieu de tester l'intersection entre deux formes statiques, nous pouvons plutôt créer de nouvelles formes en balayant les formes originales le long de leur trajectoire et en testant le chevauchement entre ces formes balayées.

L'idée de base est décrite dans [Gomez], pour les tests de balayage cercle-cercle et AABB-AABB.

- = multi-échantillonnage = -

Une alternative beaucoup plus simple aux tests balayés est le multi-échantillon; au lieu d'effectuer un seul test statique à la nouvelle position de l'objet, effectuez plusieurs tests à plusieurs positions situées entre la position précédente et la nouvelle position de l'objet. Cette technique a été utilisée pour heurter le ragdoll en N.

Si vous vous assurez que les échantillons sont toujours espacés à des distances inférieures au rayon de l'objet, cela produira d'excellents résultats. Dans notre implémentation, nous limitons le nombre maximum d'échantillons, donc des vitesses très élevées entraîneront parfois des problèmes; c'est quelque chose qui peut être modifié en fonction de votre application spécifique.

ÉDITER

En résumé et AFAIK, il y a quelques solutions

  1. Limitez votre jeu pour ne jamais avoir un petit objet et / ou un objet en mouvement rapide pouvant même provoquer
  2. Mettre en œuvre un système qui empêche les collisions de se produire, comme décrit dans le premier lien que j'ai publié
  3. Augmentez votre taux d'échantillonnage pour les objets en mouvement rapides et / ou petits
  4. ... peut-être plus, mais je ne suis pas un expert.
you786
la source
1

Cela dépend si vous souhaitez uniquement un mouvement linéaire ou si vous devez également gérer le mouvement angulaire.

Une alternative à l'utilisation de SAT:

Dans le cas de linéaire uniquement, vous pouvez lancer une projection contre la différence de Minkowski des deux polygones par rapport à l'origine dans la direction de la vitesse linéaire delta des objets.

Si le rayon frappe le MD, les deux objets entreront en collision et le point d'impact vous indiquera l'heure à laquelle ils sont entrés en collision.

Maintenant, si les objets bougent et tournent, cela devient plus difficile, mais vous pouvez toujours utiliser une technique similaire. L'avancement conservateur vous permettra de traiter cette affaire. Cette technique est itérative; chaque itération va générer un nouveau MD et vous rapprocher du moment de l'intersection.

Voici le projet de document original sur l'avancement conservateur:

http://www.continuousphysics.com/BulletContinuousCollisionDetection.pdf

J'ai écrit un article expliquant la technique en détail ici:

http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/

J'espère que ces aides!

lapin sauvage
la source