Şu anda bir koparma klonu geliştiriyorum ve düzgün çalışan bir top (daire) ve bir tuğla (dışbükey çokgen) arasındaki çarpışma tespitinde bir engel oluşturdum. Her hattın dışbükey çokgen tuğlayı temsil ettiği ve kenarladığı bir Circle-Line çarpışma algılama testi kullanıyorum.
Çoğu zaman Circle-Line testi düzgün çalışır ve çarpışma noktaları doğru şekilde çözülür.
Çarpışma algılama düzgün çalışıyor.
Ancak, top gerçekten tuğla ile kesiştiğinde, çarpışma tespit kodum bazen negatif bir ayrımcıdan dolayı yanlış döner.
Bu yöntemdeki verimsizliğin farkındayım ve test edilen tuğla sayısını azaltmak için eksene hizalanmış sınırlayıcı kutuları kullanıyorum. Temel kaygım, aşağıdaki kodumda herhangi bir matematiksel hata olup olmadığıdır.
/*
* 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);
tekrar koymayı unuttum . Aşağıdaki cevabınız için çok teşekkürler bana çok yardımcı oldu.