我发现解决这类问题的最简单方法是首先理解它们,并且具有基本的高中数学水平也会有所帮助。
解决这个问题本质上是求解具有 2 个您不知道的变量的 2 个方程:
- 你想为你的射弹找到的矢量 (
V
)
- 影响时间 (
t
)
你知道的变量是:
- 目标位置 (
P0
)
- 目标向量 (
V0
)
- 目标速度 (
s0
)
- 弹丸的来源 (
P1
)
- 弹丸速度 (
s1
)
好的,所以第一个等式是基本的。目标和弹丸的落点相同。它等于两个对象的起点+沿它们两个向量的线的一定长度。该长度由它们各自的速度和撞击时间表示。这是等式:
P0 + (t * s0 * V0) = P1 + (t * s0 * V)
请注意,这里缺少两个变量 - V
& t
,因此我们现在无法求解这个方程。进入第二个等式。
第二个等式也很直观。撞击点与弹丸原点的距离等于弹丸的速度乘以经过的时间:
我们将从第一个等式中对影响点进行数学表达式:
P0 + (t * s0 * V0) <-- point of impact
原点是P1
这两者之间的距离必须等于弹丸的速度乘以经过的时间(distance = speed * time)
。
距离的公式是:(x0 - x1)^2 + (y0 - y1)^2 = distance^2
,因此等式将如下所示:
((P0.x + s0 * t * V0.x) - P1.x)^2 + ((P0.y + s0 * t * V0.y) - P1.y)^2 = (s1 * t)^2
(您可以轻松地将其扩展为 3 个维度)
请注意,在这里,您有一个只有一个未知变量的方程:t
!。我们可以在这里发现t
是什么,然后将其放在前面的等式中并找到向量V
。
让我通过为你打开这个公式来解决你的一些痛苦(如果你真的想,你可以自己做)。
a = (V0.x * V0.x) + (V0.y * V0.y) - (s1 * s1)
b = 2 * ((P0.x * V0.x) + (P0.y * V0.y) - (P1.x * V0.x) - (P1.y * V0.y))
c = (P0.x * P0.x) + (P0.y * P0.y) + (P1.x * P1.x) + (P1.y * P1.y) - (2 * P1.x * P0.x) - (2 * P1.y * P0.y)
t1 = (-b + sqrt((b * b) - (4 * a * c))) / (2 * a)
t2 = (-b - sqrt((b * b) - (4 * a * c))) / (2 * a)
现在,请注意 - 我们将在这里获得 2 个值t
。
一个或两个可能是负数或无效数字。显然,由于t
表示时间,并且时间不能为无效或负数,因此您需要丢弃t
.
很可能两者t
都不好(在这种情况下,射弹无法击中目标,因为它更快且超出范围)。也可能是两者t
都是有效且积极的,在这种情况下,您需要选择两者中较小的一个(因为最好早点而不是晚点达到目标)。
t = smallestWhichIsntNegativeOrNan(t1, t2)
现在我们已经找到了撞击的时间,让我们找出弹丸应该飞行的方向。回到我们的第一个方程:
P0 + (t * s0 * V0) = P1 + (t * s0 * V)
现在,t
不再是缺少的变量,所以我们可以很容易地解决这个问题。只需整理方程以隔离V
:
V = (P0 - P1 + (t * s0 * V0)) / (t * s1)
V.x = (P0.x - P1.x + (t * s0 * V0.x)) / (t * s1)
V.y = (P0.y - P1.y + (t * s0 * V0.y)) / (t * s1)
就是这样,你完成了!将向量分配V
给射弹,它将到达目标所在的位置,而不是现在的位置。
我真的很喜欢这个问题,因为它需要我们在高中学习的数学方程,每个人都说“为什么要学习这个??我们永远不会在我们的生活中使用它!!”,并为它们提供了一个非常棒且实用的应用程序。
我希望这对您或其他任何试图解决此问题的人有所帮助。