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:
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.