c++ - 分离轴定理的实现不准确

标签 c++ algorithm

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 中的所有顶点都按逆时针顺序定义,并转换到世界空间中。

有什么想法吗?

example 1

example 2

屏幕截图是在检查 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/

相关文章:

c++ - 这种重载 operator new 有什么问题吗?

减少信号数据噪声的算法?

javascript - 将递归算法转换为迭代算法的困难

regex - 从排序的数字列表生成正则表达式数字范围

c++ - 如何打开特定 url 上的套接字?

c++ - 在 C++ 中使用 auto 声明变量有缺点吗?

c++ - 注册表 - 如何使用 C++ 重命名注册表中的键?

c++ - 为什么我不能将函数中定义的仿函数传递给另一个函数?

algorithm - 识别规则网格中的扭曲

python - 硬币找零问题 : difference between these two methods