bool SAT(body& b1, body& b2)
{
for (int i = 0; i < b1.edges.size(); i++)
{
vec2& v1 = b1.edges[i];
vec2& v2 = i < b1.edges.size() ? b1.edges[i + 1] : b1.edges[0];
vec2 edge = v2 - v1;
vec2 axis = edge.left();
axis.normalize();
vec2 proj1 = proj(b1, axis);
vec2 proj2 = proj(b2, axis);
float dist = interval_dist(proj1.x, proj1.y, proj2.x, proj2.y);
if (dist > 0) return false;
}
for (int i = 0; i < b2.edges.size(); i++)
{
vec2& v1 = b2.edges[i];
vec2& v2 = i < b2.edges.size() ? b2.edges[i + 1] : b2.edges[0];
vec2 edge = v2 - v1;
vec2 axis = edge.left();
axis.normalize();
vec2 proj1 = proj(b1, axis);
vec2 proj2 = proj(b2, axis);
float dist = interval_dist(proj1.x, proj1.y, proj2.x, proj2.y);
if (dist > 0) return false;
}
return true;
}
float interval_dist(float minA, float maxA, float minB, float maxB)
{
if (minA < minB)
{
return minB - maxA;
}
else {
return minA - maxB;
}
}
vec2 proj(body& b, vec2& axis)
{
float min = dot(b.edges[0], axis);
float max = min;
for (int i = 1; i < b.edges.size(); i++)
{
float dt = dot(b.edges[i], axis);
if (dt < min)min = dt;
if (dt > max)max = dt;
}
return vec2(min, max);
}
vec2::vec2 left()
{
return vec2(-y, x);
}
我得到的结果可能与我在屏幕上看到的有很大不同。两个物体可能彼此相距很远(虽然不是很远),但 SAT 返回 true。或者两个物体可以相互碰撞,所以 SAT 在实际碰撞时刻是“迟到的”。
body 中的所有顶点都按逆时针顺序定义,并转换到世界空间中。
有什么想法吗?
屏幕截图是在检查 SAT 是否返回 true 后立即在 Debug模式下截取的。
最佳答案
在SAT
,这似乎没有达到预期目的:
vec2& v2 = i < b1.edges.size() ? b1.edges[i + 1] : b1.edges[0];
i < b1.edges.size()
自 i
以来将始终为真永远不会达到 b1.edges.size()
.相反,您可能想与 b1.edges.size() - 1
进行比较:
vec2& v2 = i < b1.edges.size() - 1 ? b1.edges[i + 1] : b1.edges[0];
第二个循环也是如此。
关于c++ - 分离轴定理的实现不准确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33856494/