Théorème de l'axe de séparation de JavaScript

J'essaie d'enrouler la tête en utilisant le théorème de l'axe de séparation en JavaScript pour détecter deux collisions en cas de collision (l'une tournée, l'une non). Aussi difficile que j'essaie, je ne peux pas comprendre ce que cela ressemblerait en JavaScript, et je ne peux pas trouver d'exemples de JavaScript. Aidez-nous, une explication avec un code simple ou un code JavaScript serait très utile.


Mise à jour: Après avoir recherché beaucoup de théories géométriques et mathématiques, j'ai décidé de déployer une implémentation SAT simplifiée dans un compte GitHub. Vous pouvez trouver une copie de travail de SAT en JavaScript ici: https://github.com/ashblue/canvas-sat

Transformer des polygones

Tout d'abord, vous devez transformer tous les points de vos polygones convexes (carrés dans ce cas) afin qu'ils soient tous dans le même espace, en appliquant une rotation d' angle .

Pour un support futur de la mise à l'échelle, de la traduction, etc. Je recommande de le faire par des transformations matricielles. Vous devrez coder votre propre classe Matrix ou trouver une bibliothèque qui a déjà cette fonctionnalité (je suis sûr qu'il existe beaucoup d'options).

Ensuite, vous utiliserez le code dans le but de:

 var transform = new Matrix(); transform.appendRotation(alpha); points = transform.transformPoints(points); 

Où les points sont un ensemble d'objets Point ou plus.

Aperçu de l'algorithme de collision

Donc c'est tout avant d'arriver à toute collision. En ce qui concerne l'algorithme de collision, il est standard d'essayer de séparer 2 polygones convexes (carrés dans votre cas) en procédant comme suit:

  • Pour chaque bord du polygone (bords du polygone 0 et du polygone 1):
    • Classifiez les deux polgyons comme "en face", "s'étendant" ou "derrière" le bord.
    • Si les deux polygones sont sur des côtés différents (1 "en face" et 1 "derrière"), il n'y a pas de collision, et vous pouvez arrêter l'algorithme (sortie anticipée).
  • Si vous arrivez ici, aucun bord n'a été capable de séparer les polyrônes: les polygones se croisent ou se heurtent.

Notez que conceptuellement, l'axe de séparation est l'axe perpendiculaire au bord avec lequel nous classons les polygones.

Classer des polygones en regard d'un bord

Pour ce faire, nous classerons les points / sommets d'un polygone en ce qui concerne le bord. Si tous les points sont d'un côté, le polygone est de ce côté. Sinon, le polygone s'étend sur le bord (partiellement d'un côté, partiellement de l'autre côté).

Pour classer les points, nous devons d'abord avoir le bord normal:

 // this code assumes p0 and p1 are instances of some Vector3D class var p0 = edge[0]; // first point of edge var p1 = edge[1]; // second point of edge var v = p1.subtract(p0); var normal = new Vector3D(0, 0, 1).crossProduct(v); normal.normalize(); 

Le code ci-dessus utilise le produit croisé de la direction de bord et le vecteur z pour obtenir la normale. Bien sûr, vous devriez pré-calculer cela pour chaque bord à la place.

Remarque: La normale représente l'axe de séparation du SAT.

Ensuite, nous pouvons classer un point arbitraire en le faisant d'abord par rapport au bord (en soustrayant un point de bord) et en utilisant le produit à point avec la normale:

 // point is the point to classify as "in front" or "behind" the edge var point = point.subtract(p0); var distance = point.dotProduct(normal); var inFront = distance >= 0; 

Maintenant, inFront est true si le point est en avant ou sur le bord, et false sinon.

Notez que lorsque vous gérez les points d'un polygone pour classer le polygone, vous pouvez également quitter tôt si vous avez au moins 1 point devant et 1 derrière, puisqu'il est déjà déterminé que le polygone s'étend sur le bord (et non devant Ou derrière).

Donc, comme vous pouvez le voir, vous avez encore beaucoup de codage à faire. Trouvez une bibliothèque js avec des classes Matrix et Vector3D ou plus et utilisez-la pour implémenter ce qui précède. Représentez vos formes de collision (polygones) en tant que séquences d'instances Point and Edge .

J'espère que cela vous permettra de commencer.