J'essaie d'écrire ma propre implémentation du théorème de l'axe de séparation, mais j'ai du mal à le faire fonctionner aussi précisément que je le veux. Je ne peux pas le dire avec certitude, mais on dirait qu'il y a une collision quand une boîte imaginaire autour des formes se heurte comme dans la première forme. Mais la deuxième forme fonctionne parfaitement.Implémentation de détection de collision de polygone
est ici les données de sommet pour le carré (coordonnées exactes):
vertsx = [ 200, 220, 220, 200 ]
vertsy = [ 220, 220, 200, 200 ]
Voici les données de sommet pour la forme de test 1 (par rapport à la souris):
vertsx = [ -10, 0, 10, 10, -10 ]
vertsy = [ -10, -50, -10, 10, 10 ]
Enfin voici les données de sommet pour la forme de test 2 (par rapport à la souris):
vertsx = [ -10, 0, 10, 10, -10 ]
vertsy = [ -10, -20, -10, 10, 10 ]
Juste pour clarifier le roumain traduit rdinates sont ceux qui sont testés et ceux-ci ont des formes ont été testés avec les coordonnées ordonnées comme indiqué.
est ici la fonction réelle.
function collisionConvexPolygon (vertsax, vertsay, vertsbx, vertsby) {
var alen = vertsax.length;
var blen = vertsbx.length;
// Loop for axes in Shape A
for (var i = 0, j = alen - 1; i < alen; j = i++) {
// Get the axis
var vx = vertsax[ j ] - vertsax[ i ];
var vy = -(vertsay[ j ] - vertsay[ i ]);
var len = Math.sqrt(vx * vx + vy * vy);
vx /= len;
vy /= len;
// Project shape A
var max0 = vertsax[ 0 ] * vx + vertsay[ 0 ] * vy, min0 = max0;
for (k = 1; k < alen; k++) {
var proja = vertsax[ k ] * vx + vertsay[ k ] * vy;
if (proja > max0) {
max0 = proja;
}
else if (proja < min0) {
min0 = proja;
}
}
// Project shape B
var max1 = vertsbx[ 0 ] * vx + vertsby[ 0 ] * vy, min1 = max1;
for (var k = 1; k < blen; k++) {
var projb = vertsbx[ k ] * vx + vertsby[ k ] * vy;
if (projb > max1) {
max1 = projb;
}
else if (projb < min1) {
min1 = projb;
}
}
// Test for gaps
if (!axisOverlap(min0, max0, min1, max1)) {
return false;
}
}
// Loop for axes in Shape B (same as above)
for (var i = 0, j = blen - 1; i < blen; j = i++) {
var vx = vertsbx[ j ] - vertsbx[ i ];
var vy = -(vertsby[ j ] - vertsby[ i ]);
var len = Math.sqrt(vx * vx + vy * vy);
vx /= len;
vy /= len;
var max0 = vertsax[ 0 ] * vx + vertsay[ 0 ] * vy, min0 = max0;
for (k = 1; k < alen; k++) {
var proja = vertsax[ k ] * vx + vertsay[ k ] * vy;
if (proja > max0) {
max0 = proja;
}
else if (proja < min0) {
min0 = proja;
}
}
var max1 = vertsbx[ 0 ] * vx + vertsby[ 0 ] * vy, min1 = max1;
for (var k = 1; k < blen; k++) {
var projb = vertsbx[ k ] * vx + vertsby[ k ] * vy;
if (projb > max1) {
max1 = projb;
}
else if (projb < min1) {
min1 = projb;
}
}
if (!axisOverlap(min0, max0, min1, max1)) {
return false;
}
}
return true;
}
Je vais essayer d'autres formes si vous avez besoin de moi.
Voici ma fonction axisOverlap
.
function axisOverlap (a0, a1, b0, b1) {
return !(a0 > b1 || b0 > a1);
}
Pouvez-vous publier votre 'axisOverlap()' fonction aussi? – techfoobar
Pourriez-vous s'il vous plaît essayer ceci sans inverser la direction de vy? –
@Asad Oui, malheureusement, il n'a pas changé le résultat. – SpaceFace