Saat ini saya sedang mengembangkan klon breakout dan saya telah memukul hambatan dalam mendapatkan deteksi tabrakan antara bola (lingkaran) dan batu bata (cembung poligon) yang bekerja dengan benar. Saya menggunakan tes deteksi tabrakan Circle-Line di mana setiap baris mewakili dan tepi pada bata cembung poligon.
Untuk sebagian besar waktu, tes Circle-Line bekerja dengan baik dan titik-titik tabrakan diselesaikan dengan benar.
Deteksi tabrakan bekerja dengan benar.
Namun, kadang-kadang kode deteksi tabrakan saya mengembalikan false karena diskriminan negatif ketika bola benar-benar memotong bata.
Saya menyadari inefisiensi dengan metode ini dan saya menggunakan kotak kotak yang sejajar untuk mengurangi jumlah batu bata yang diuji. Perhatian utama saya adalah jika ada bug matematika dalam kode saya di bawah ini.
/*
* 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);
kembali. Terima kasih banyak atas jawaban Anda di bawah ini banyak membantu saya.