Tôi hiện đang phát triển một bản sao đột phá và tôi đã đạt được một rào cản trong việc phát hiện va chạm giữa một quả bóng (vòng tròn) và một viên gạch (đa giác lồi) hoạt động chính xác. Tôi đang sử dụng thử nghiệm phát hiện va chạm Circle-Line trong đó mỗi dòng đại diện và cạnh trên gạch đa giác lồi.
Trong phần lớn thời gian, kiểm tra Circle-Line hoạt động chính xác và các điểm va chạm được giải quyết chính xác.
Phát hiện va chạm làm việc chính xác.
Tuy nhiên, đôi khi mã phát hiện va chạm của tôi trả về sai do phân biệt đối xử âm khi bóng thực sự giao nhau với gạch.
Phát hiện va chạm không thành công.
Tôi nhận thức được sự không hiệu quả của phương pháp này và tôi đang sử dụng các hộp giới hạn căn chỉnh trục để cắt giảm số lượng gạch được thử nghiệm. Mối quan tâm chính của tôi là nếu có bất kỳ lỗi toán học nào trong mã của tôi dưới đây.
/*
* 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);
lại. Cảm ơn rất nhiều vì câu trả lời của bạn bên dưới nó đã giúp tôi rất nhiều.