值得预先计算一次碰撞事件(这种方法适用于可靠数量的球,因为我们必须处理所有~n^2 球对)。
第一个球的位置是A0,速度矢量是VA。
第二个球的位置是B0,速度矢量是VB。
为了简化计算,我们可以使用 Halileo 原理——使用与第一个球相连的移动坐标系。在那个系统中,第一个球的位置和速度总是为零。对时间的第二个球位置是:
B'(t) = (B0 - A0) + (VB - VA) * t = B0' + V'*t
我们只需要找到碰撞二次方程的解distance=2R:
(B0'.X + V'.X*t)^2 + (B0'.X + V'.Y*t)^2 = 4*R^2
在未知时间t 求解这个方程,我们可能会遇到以下情况:无解(无碰撞)、单一解(仅触摸事件)、两个解 - 在这种情况下,较小的 t 值对应于物理时刻碰撞。
示例(抱歉,在 Python 中,** 是幂运算符):
def collision(ax, ay, bx, by, vax, vay, vbx, vby, r):
dx = bx - ax
dy = by - ay
vx = vbx - vax
vy = vby - vay
#(dx + vx*t)**2 + (dy + vy*t)**2 == 4*r*r solve this equation
#coefficients
a = vx**2 + vy**2
b = 2*(vx*dx + vy*dy)
c = dx**2+dy**2 - 4*r**2
dis = b*b - 4*a*c
if dis<0:
return None
else:
t = 0.5*(-b - dis**0.5)/a ##includes case of touch when dis=0
return [(ax + t * vax, ay + t * vay), (bx + t * vbx, by + t * vby)]
print(collision(0,0,100,0,50,50,-50,50,10)) #collision
print(collision(0,0,100,0,50,50,-50,80,10)) #miss
print(collision(0,0,100,0,100,0,99,0,10)) #long lasting chase along OX axis
[(40.0, 40.0), (60.0, 40.0)]
None
[(8000.0, 0.0), (8020.0, 0.0)]