真正的問題是找出子彈可以與目標路徑相交的空間。子彈的速度是恆定的,所以在一定的時間內,無論我們開火的方向如何,它都會移動相同的距離。這意味着它在時間t之後的位置將永遠位於球體上。下面是一個醜陋圖解2D:
該球可以在數學上表示爲:
(x-x_b0)^2 + (y-y_b0)^2 + (z-z_b0)^2 = (bulletSpeed * t)^2 (eq 1)
x_b0,y_b0和z_b0表示大炮的位置。
targetPos+t*targetVelocityVec (eq 2)
(eq 2)
是一個矢量方程,可以分解成三個獨立的方程:
x = x_t0 + t * v_x
y = y_t0 + t * v_y
z = z_t0 + t * v_z
這三個可以使用在你的問題中提供的方程求解這個方程找不到時間t方程可以被插入到(eq 1)
:
(x_t0 + t * v_x - x_b0)^2 + (y_t0 + t * v_y - y_b0)^2 + (z_t0 + t * v_z - z_b0)^2 = (bulletSpeed * t)^2
該方程僅包含已知的變量和可以解決對於t。由二次子表達式的常數部分分配給常數,我們可以簡化計算:
c_1 = x_t0 - x_b0
c_2 = y_t0 - y_b0
c_3 = z_t0 - z_b0
(v_b = bulletSpeed)
(t * v_x + c_1)^2 + (t * v_y + c_2)^2 + (t * v_z + c_3)^2 = (v_b * t)^2
重新排列其作爲一個標準的二次方程:
(v_x^2+v_y^2+v_z^2-v_b^2)t^2 + 2*(v_x*c_1+v_y*c_2+v_z*c_3)t + (c_1^2+c_2^2+c_3^2) = 0
這是容易解決使用標準公式。它可以導致零個,一個或兩個解決方案。零解決方案(不包括複雜的解決方案)意味着子彈無法達到目標。當目標軌跡與球體的邊緣相交時,一種解決方案可能很少發生。兩種解決方案將是最常見的情況。否定的解決方案意味着你不能擊中目標,因爲你需要將子彈射入過去。這些都是你必須檢查的條件。
當你解決了方程式,你可以找到t的位置,把它放回(eq 2)
。在僞代碼:
# setup all needed variables
c_1 = x_t0 - x_b0
c_2 = y_t0 - y_b0
c_3 = z_t0 - z_b0
v_b = bulletSpeed
# ... and so on
a = v_x^2+v_y^2+v_z^2-v_b^2
b = 2*(v_x*c_1+v_y*c_2+v_z*c_3)
c = c_1^2+c_2^2+c_3^2
if b^2 < 4*a*c:
# no real solutions
raise error
p = -b/(2*a)
q = sqrt(b^2 - 4*a*c)/(2*a)
t1 = p-q
t2 = p+q
if t1 < 0 and t2 < 0:
# no positive solutions, all possible trajectories are in the past
raise error
# we want to hit it at the earliest possible time
if t1 > t2: t = t2
else: t = t1
# calculate point of collision
x = x_t0 + t * v_x
y = y_t0 + t * v_y
z = z_t0 + t * v_z
考慮彈丸遵循筆直的軌跡,使問題變得頗爲無趣:-( – salva 2011-01-21 15:21:37