如何在三维空间中找到移动目标的拦截坐标?

Xen*_*oRo 4 math 3d position prediction coordinates

假设我有一艘宇宙飞船(source); 小行星(target)就在附近.

我知道,在3D空间(XYZ向量):

  • 我的船的位置(sourcePos)和速度(sourceVel).
  • 小行星的位置(targetPos)和速度(targetVel).

(例如sourcePos= [30,20,10]; sourceVel= [30,20,10]; targetPos= [600,400,200]; targetVel= [300,200,100]`)

我也知道:

  • 船的速度恒定的.
  • 小行星的速度恒定的.
  • 我的船的抛射速度(projSpd)是恒定的.
  • 射击后我的船的弹丸轨迹线性的(/直的).

(例如projSpd= 2000.00)

如何计算我需要射击的拦截坐标以击中小行星?


笔记:

这个问题是基于这个Yahoo - Answers页面.

我也在谷歌搜索类似的问题,在这里搜索SO,但大多数答案都是针对2D空间的,而对于3D的少数答案,解释和伪代码都没有解释什么是做什么和/或为什么,所以我不能真正理解将它们成功应用于我的代码.以下是我访问过的一些页面:

Danik Games Devlog,Blitz3D论坛主题,UnityAnswers,StackOverflow#1,StackOverflow#2


我真的无法弄清楚链接页面上的数学/执行流程,除非有人将其(进一步)分析为正在做什么,为什么;
提供一个经过适当评论的伪代码供我遵循;
或者至少指出我实际解释方程如何工作的链接,而不仅仅是在我已经混淆的心灵中抛出更多的随机数和不可跟随的方程式.

Gil*_*yof 10

我找到了解决这些问题的最简单的方法,首先要理解它们,并且拥有基本的高中数学水平也会有所帮助.

解决这个问题基本上解决了2个方程,其中包含2个您不知道的变量:

  1. 你想要为你的射弹找到的矢量(V)
  2. 影响时间(t)

你知道的变量是:

  1. 目标的位置(P0)
  2. 目标的向量(V0)
  3. 目标的速度(s0)
  4. 抛射物的起源(P1)
  5. 抛射物的速度(s1)

好的,所以第一个等式是基本的.目标和射弹的撞击点是相同的.它等于两个物体的起始点+沿着它们两个矢量线的一定长度.该长度由它们各自的速度和冲击时间表示.这是等式:

P0 + (t * s0 * V0) = P1 + (t * s0 * V)
Run Code Online (Sandbox Code Playgroud)

请注意,这里有两个缺失的变量 - V&t,因此我们现在无法解决这个等式.到第二个等式.

第二个等式也非常直观.撞击点与射弹原点的距离等于射弹的速度乘以经过的时间:

我们将从第一个等式中得出影响点的数学表达式:

P0 + (t * s0 * V0) <-- point of impact
Run Code Online (Sandbox Code Playgroud)

原点是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 
Run Code Online (Sandbox Code Playgroud)

(您可以轻松地将其扩展为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)
Run Code Online (Sandbox Code Playgroud)

现在,注意 - 我们将t在这里获得2个值.

一个或两个可能是否定数字或无效数字.显然,由于t表示时间,时间不能无效或为负,您需要丢弃这些值t.

很可能两者t都很糟糕(在这种情况下,射弹无法击中目标,因为它更快且超出范围).也可能是两者t都是有效的和正面的,在这种情况下你会想要选择两者中较小的一个(因为它最好是尽快击中目标而不是更晚).

t = smallestWhichIsntNegativeOrNan(t1, t2)
Run Code Online (Sandbox Code Playgroud)

现在我们已经找到了影响的时间,让我们看看射弹的飞行方向是什么.回到我们的第一个等式:

P0 + (t * s0 * V0) = P1 + (t * s0 * V)
Run Code Online (Sandbox Code Playgroud)

现在,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) 
Run Code Online (Sandbox Code Playgroud)

就是这样,你完成了!将矢量分配V给射弹,它将到达目标的位置而不是现在的位置.

我真的很喜欢这个问题,因为它需要我们在高中学到的数学方程,每个人都说"为什么学习这个?我们永远不会在生活中使用它!",并给它们一个非常棒的实用应用.

我希望这可以帮助你,或任何试图解决这个问题的人.