math - 如何在3D空间中找到移动目标的交点坐标?

标签 math 3d position coordinates prediction

假设我有一艘宇宙飞船(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/

    相关文章:

    math - 如何使用Dart计算此数学?

    JavaFX 2D 变换矩阵的仿射变换

    CSS 页脚 - 左手元素高于右手元素

    c++ - 动态整数大小 : int64_t, int32_t、uint32_t 等

    c# - 将小数简化为分数的算法

    c# - 如何在 WPF 中为 Viewport3D 控件切换到线框显示模式?

    python - Pyplot 3d 散点图 : points at the back overlap points at the front

    delphi - 如何根据屏幕上的 X、Y 坐标返回颜色?

    javascript - 只有相对定位的 child 元素的自动高度

    python - Python中所有向量组合的集合