假设我有一艘宇宙飞船(source
);附近有一颗小行星 (target
)。
我知道,在 3D 空间(XYZ 向量)中:
sourcePos
)和速度(sourceVel
)。 targetPos
)和速度(targetVel
)。 (例如。
sourcePos
= [30, 20, 10]; sourceVel
= [30, 20, 10]; targetPos
= [600, 400, 200]; targetVel
= [301] `)我也知道:
projSpd
) 是恒定的。 (例如。
projSpd
= 2000.00)如何计算我需要射击以击中小行星的拦截坐标?
笔记:
这个问题基于 this Yahoo - Answers page 。
我还在 Google 和 SO 上搜索了类似的问题,但是大多数答案都是针对 2D 空间的,并且在少数针对 3D 的答案中,解释和伪代码都没有解释正在做什么和/或为什么,所以我无法真正理解到将它们成功应用到我的代码中。以下是我访问过的一些页面:
Danik Games Devlog , Blitz3D Forums thread , UnityAnswers , StackOverflow #1 , StackOverflow #2
我真的无法弄清楚链接页面上的数学/执行流程,除非有人(进一步)剖析它在做什么,以及为什么;
提供正确注释的伪代码供我遵循;
或者至少将我指向实际解释方程如何工作的链接,而不是仅仅在我已经困惑的心灵中抛出更多随机数和无法遵循的方程。
最佳答案
我发现解决这些问题的最简单方法是首先理解它们,并且拥有基本的高中数学水平也会有所帮助。
解决这个问题本质上是用你不知道的 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)
现在,请注意 - 我们将获得
t
的 2 个值这里。一个或两个可能是负数或无效数字。显然,由于
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
到射弹,它将前往目标所在的位置,而不是现在的位置。我真的很喜欢这个问题,因为它需要我们在高中学习的数学方程,每个人都说“为什么要学这个??我们永远不会在我们的生活中使用它!!”,并为他们提供了一个非常棒和实际的应用程序。
我希望这对您或任何其他试图解决此问题的人有所帮助。
关于math - 如何在3D空间中找到移动目标的交点坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17204513/