一个简单的2D矩形碰撞算法,该算法还可以确定矩形碰撞的边?


16

我最初尝试实现矩形相交,效果很好。但是,当我必须应用物理系统(例如速度,加速度和方向矢量)时,我将不得不找到一种方法来确定矩形的哪一侧发生碰撞。现在,在我的系统中,没有旋转的矩形,因此这简化了问题。但是,我找不到确定哪个矩形边发生碰撞的简便方法。我曾经处理过这个问题,但失败了。

我过去所做的是确定每个平行矩形边之间的距离,并检查该距离是否接近0(使用一些初始定义的距离范围)或为0。但是,对于浮点算法,这证明是不稳定的,因为未知时间的流逝。有时,这些矩形实际上会在满足定义范围之前相交。

另一方面,我正在考虑生成多个矩形,每个矩形各边。但是,再三考虑之后,将其与平行边进行距离范围检查是一样的,只是该距离范围就是每个微型矩形的宽度。

因此,对这个问题有什么建议吗?


您正在使用离散或连续位置更新吗?(您是通过每帧一次通过加速度来更新速度,然后计算位置,还是使用函数来推断位置)
Casey Kuball 2012年

Answers:


24

改编自我对“打哪面?”的回答

我建议计算闵可夫斯基和 B和A,这是一个新的矩形,并检查其中矩形A所在的中心相对,以新的矩形(要知道是否碰撞正在发生的事情)和它的对角线(要知道这里碰撞正在发生):

float w = 0.5 * (A.width() + B.width());
float h = 0.5 * (A.height() + B.height());
float dx = A.centerX() - B.centerX();
float dy = A.centerY() - B.centerY();

if (abs(dx) <= w && abs(dy) <= h)
{
    /* collision! */
    float wy = w * dy;
    float hx = h * dx;

    if (wy > hx)
        if (wy > -hx)
            /* collision at the top */
        else
            /* on the left */
    else
        if (wy > -hx)
            /* on the right */
        else
            /* at the bottom */
}

1
我想补充一点,“顶部”和“底部”是相对于您的坐标系的。例如,在我的游戏中,(0,0)位于左上方,因此它们与您的示例相反。只是要记住一点。
Neikos

很好的解决方案,非常适合我的需求。
Opiatefuchs

1
dx变为0或dy变为0或两者都出现故障吗?让我说明一下...如果dx = 0 && dy == 0,这意味着两个矩形都在同一原点上,那么该算法默认返回底部?如果它们之一为0,则预期结果正确。因此,我认为,除了dx == 0 && dy == 0的情况应该是不确定的而不是最低的,这种算法是正确的。因此,当心并感谢。
Prasanth

1
现在,我想知道当dx == dy,w == h ...时会发生什么。然后,代码也确定当结果实际上不确定时,结果是一侧。.想象两个相交的正方形,使得一个正方形的中心在另一个正方形的一个角,另一个正方形的中心在第一个正方形的角。在这里,侧面应该是不确定的-它不是正确的也不是底部。都是吗?
Prasanth
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.