Je développe actuellement un clone de cassure et j'ai réussi à bloquer la détection de collision entre une balle (cercle) et une brique (polygone convexe) qui fonctionne correctement. J'utilise un test de détection de collision Circle-Line où chaque ligne représente et arête sur la brique polygone convexe.
La plupart du temps, le test Circle-Line fonctionne correctement et les points de collision sont résolus correctement.
La détection de collision fonctionne correctement.
Cependant, parfois, mon code de détection de collision retourne faux en raison d'un discriminant négatif lorsque la balle intersecte réellement la brique.
Échec de la détection de collision.
Je suis conscient de l'inefficacité de cette méthode et j'utilise des boîtes englobantes alignées sur l'axe pour réduire le nombre de briques testées. Ma principale préoccupation est s'il y a des bugs mathématiques dans mon code ci-dessous.
/*
* from and to are points at the start and end of the convex polygons edge.
* This function is called for every edge in the convex polygon until a
* collision is detected.
*/
bool circleLineCollision(Vec2f from, Vec2f to)
{
Vec2f lFrom, lTo, lLine;
Vec2f line, normal;
Vec2f intersectPt1, intersectPt2;
float a, b, c, disc, sqrt_disc, u, v, nn, vn;
bool one = false, two = false;
// set line vectors
lFrom = from - ball.circle.centre; // localised
lTo = to - ball.circle.centre; // localised
lLine = lFrom - lTo; // localised
line = from - to;
// calculate a, b & c values
a = lLine.dot(lLine);
b = 2 * (lLine.dot(lFrom));
c = (lFrom.dot(lFrom)) - (ball.circle.radius * ball.circle.radius);
// discriminant
disc = (b * b) - (4 * a * c);
if (disc < 0.0f)
{
// no intersections
return false;
}
else if (disc == 0.0f)
{
// one intersection
u = -b / (2 * a);
intersectPt1 = from + (lLine.scale(u));
one = pointOnLine(intersectPt1, from, to);
if (!one)
return false;
return true;
}
else
{
// two intersections
sqrt_disc = sqrt(disc);
u = (-b + sqrt_disc) / (2 * a);
v = (-b - sqrt_disc) / (2 * a);
intersectPt1 = from + (lLine.scale(u));
intersectPt2 = from + (lLine.scale(v));
one = pointOnLine(intersectPt1, from, to);
two = pointOnLine(intersectPt2, from, to);
if (!one && !two)
return false;
return true;
}
}
bool pointOnLine(Vec2f p, Vec2f from, Vec2f to)
{
if (p.x >= min(from.x, to.x) && p.x <= max(from.x, to.x) &&
p.y >= min(from.y, to.y) && p.y <= max(from.y, to.y))
return true;
return false;
}
sqrt_disc = sqrt(disc);
. Merci beaucoup pour votre réponse ci-dessous, cela m'a beaucoup aidé.