球撞到角落,它将在哪里偏转?


46

我需要复习三角函数,希望您可以通过简单的数学模型为您提供帮助。到目前为止,这是我在模型中附加的模型。我知道当球快速移动时帧动画还有其他问题,但是现在我只需要计算ballDx和ballDy。ballDx = 0(仅垂直运动)也是可能的,但是当球偏斜时,ballDx可能会获得不同的值。

球与固体不可移动物体的角边缘之间的2D碰撞


22
这就是他们所说的“拐角案件”吗?
Andrew Grimm

2
可以肯定的是,随着时间的流逝,我们可能很快会采用相对论来解决它-问题正在变得越来越普遍。
Lumis

Answers:


45

注意:以下所有条件均假设球的表面无摩擦(因此不会开始旋转或反弹,因为它确实如此)。

碰撞时,球将碰到角球。当固体物体碰撞时,力将沿着所谓的表面法线(即垂直于碰撞点处的表面)作用。

由于它是球,因此垂直于表面的方向是球的中心。好的,所以我们知道了力的方向,力的大小呢?假设发生弹性碰撞(并且矩形不能移动),则球必须以与撞击时相同的速度反弹。

令(nDx,nDy)为碰撞后的速度,(oDx,oDy)为碰撞前的速度,(x,y)为球在碰撞点的位置。让我们进一步假设球碰撞的角在(0,0)。

以公式表示我们的见解,我们有:

(nDx, nDy) = (oDx, oDy) + c * (x, y)
length (nDx, nDy) = length (oDx, oDy)

等效于:

nDx = oDx + c * x
nDy = oDy + c * y
nDx^2 + nDy^2 = oDx^2 + oDy^2

将前两个方程式替换为最后一个方程式,我们得到:

(oDx + c * x)^2 + (oDy + c * y)^2 = oDx^2 + oDy^2

使用二项式定理扩展

(a+b)^2 = a^2 + 2ab + b^2 

产量:

oDx^2 + 2 * oDx * c * x + (c * x) ^ 2 + oDy^2 + 2 * oDy * c * y + (c * y) ^ 2 = oDx^2 + oDy^2
2 * oDx * c * x + 2 * oDy * c * y + (c * x) ^ 2 + (c * y) ^ 2 = 0
(2 * oDx * x + 2 * oDy * y) * c + (x^2 + y^2) * c^2 = 0

这个二次方程式c有两个解,其中一个为0。显然,这不是我们感兴趣的解,因为通常球的方向会因碰撞而改变。为了获得其他解决方案,我们将双方除以c并得到:

(2 * oDx * x + 2 * oDy * y) + (x^2 + y^2) * c = 0

那是:

 c = -(2 * oDx * x + 2 * oDy * y) / (x^2 + y^2)

总而言之,我们有:

c = -(2 * oDx * x + 2 * oDy * y) / (x^2 + y^2)
nDx = oDx + c * x
nDy = oDy + c * y

编辑:在代码中:

if (collision) {
    float x = ballX - cornerX;
    float y = ballY - cornerY;
    float c = -2 * (ballDx * x + ballDy * y) / (x * x + y * y);
    ballDx = ballDx + c * x;
    ballDy = ballDy + c * y;
}

一些实施注意事项:尽管您可以在模拟步骤之后用球的位置来近似(x,y),但是这种近似会改变偏转角度,因此非常引人注目,因此您的模拟步骤必须非常精细(也许这样球每步移动不超过其直径的1/20)。为了获得更准确的解决方案,您可以计算发生碰撞的时间,并在该时间拆分该模拟步骤,即执行一个局部步骤直到碰撞点,然后执行另一个局部步骤以完成其余步骤。

编辑2:计算影响点

令r为半径,(x0,y0)为位置,(dx,dy)为模拟步骤开始时球的速度。为简单起见,让我们进一步假设所讨论的角位于(0,0)。

我们知道:

(x,y) = (x0, y0) + (dx, dy) * t

我们想要

length(x,y) = r

那是

(x0 + dx * t) ^ 2 + (y0 + dy * t) ^ 2 = r^2
x0^2 + 2 * x0 * dx * t + dx^2 * t^2 + y0^2 + 2 * y0 * dy * t + dy^2 * t^2 = r ^ 2
(dx^2 + dy^2) * t^2 + (2 * x0 * dx + 2 * y0 * dy) * t + (x0^2 + y0^2 - r^2) = 0
\____  _____/         \____________  ___________/       \_______  ________/
     \/                            \/                           \/
     a                             b                            c

那是t中的二次方程。如果有区别

D = b^2 - 4 * a * c

如果为负,则没有解决方案,即,球永远不会撞到当前路线的角落。否则,它的两个解由

t1 = (-b - sqrt(D)) / (2 * a)
t2 = (-b + sqrt(D)) / (2 * a)

我们对碰撞开始的时间感兴趣,这是更早的时间t1

您的方法将变为:

    // compute a,b,c and D as given above

    if (D >= 0) {
        t = (-b - sqrt(D)) / (2 * a);
        if (0 < t && t <= ts) {
            // collision during this timestep!

            x = x + t * dx;
            y = y + t * dy;
            ts = ts - t;

            // change dx and dy using the deflection formula 
        }
    }

    x = x + ts * dx;
    y = y + ts * dy;

1
这值得+1
动态

1
随时投票

3
您很早就说过,At the moment of collision, the ball will be touching the corner但是我没有看到这种近似的合理性(它必须是一种近似,因为它不是正确的-球在两个位置接触,两个都不在角落)。
彼得·泰勒

1
@Peter Taylor:您确实注意到OP将球绘制到矩形外部,问题中给出的碰撞检测公式也以此为前提?您必须在这里
跳出框框

1
喜欢这个答案,但是它可以使用数学上的$ \ LaTeX $标记。
Martin Wickman

13

这是解决问题的一种直观方法。

最初的问题集是圆形与矩形(下图中的灰色)。这等效于点与圆角矩形(以黑色显示)。

因此,这是一个多部分的问题。您正在测试点碰撞与4条线(从框的边缘伸出原始圆的半径)和4条圆(在与原始圆半径相同的矩形角处)之间的碰撞。

以原始图像中的粗略速度,该点将命中右下角的圆。您所要做的就是找出您要撞到的角圆上的点,计算该角度并从中反射出来。

在此处输入图片说明

我会将其派生作为练习留给读者。


2

我正在开发游戏,也被困在这里。但是我想这是这样的:

在此处输入图片说明

还有另一种观点, 我的问题是我不知道如何快速计算新的dx,dy(对我而言,使用传统数学运算需要太多计算)。


我的观点与第二个链接中的观点不同,因为我不认为新的速度矢量像那样取决于块的中心。我的兄弟告诉我,球会弹回原来的方向(dx = -dx && dy =-dy),但我不这么认为。
里萨

如果球击中角球,并且ballX与cornerX的距离小于ballW的1/4,则它将弹回,否则它将向右偏转。这是我目前正在使用的简单模型,无法微调以找到确切的角度。
Lumis

0

运动学就是选择正确的参考系,因为对于计算最方便

在这里,我们将首先定义变换T,该变换将我们的轴分解为与球的中心和角之间的线平行(x')和垂直(y')的分量。逆变换T *将恢复我们的原始坐标系。

在这个新的参考系中,通过反射(以及物理学的时间和空间对称性),我们得到了接触M的速度变换(一个点冲量),它使x'分量反转而使y'分量不变。用矩阵术语来说,这是对角矩阵,对角线上有-1和1。

那么碰撞后的速度就是:V' = T *中号ŤVO

的碰撞时然后只为溶液(Ť)+(XŤVO)()= - [R ,其中X是X轴投影算子和- [R是球的半径。重新排列,我们得到
=([R - (Ť景点))/((XŤVO)())

这具有将所有复杂的数学都埋入严格编写,测试和调试的标准图形库中的明显优势。对于2D和3D情况,此解决方案也相同-只需切换图形库即可。最后,它强调指出,在解决任何物理问题之前,首先应考虑适当的参考系。总是有NIH的诱惑,但是实际上,当可以提供更多简洁的解决方案时,这仅仅是bug的秘诀。

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.