Find direction to hit moving target(向移动目标发射子弹)

Find direction to hit moving target (Firing bullet at moving target)

我已经阅读了 stackexchange 上的其他几种解决方案,但没有找到解决此问题的直接方法。

我有一个 sourcePointtargetPoint。目标有 targetVelocity(速度和方向),源有 sourceSpeed.

我需要一种方法来计算 sourceDirection(使用 sourceSpeed 变成 sourceVelocity

我一直在研究数学,它一定是某种等式,其中函数有时可能 return 为假,即。子弹追不上目标,取决于targetVelocitysourceSpeed

我当前的解决方案给出了一个方向,但没有考虑到达目标所需的额外长度,因为它基于射击时的目标长度。

另外,如果我能避免 Sqrt/Normalize 这对性能会很好,但我正在寻找相当 simple/elegant 的解决方案。

    /// Returns sourceVelocity
    public static Vector2 calcBullet(Vector2 source, float sourceSpeed, Vector2 target, Vector2 targetVelocity)
    {
        var diff = target - source;
        var dist = Vector2.Distance(diff, Vector2.Zero);
        diff += targetVelocity * (dist / sourceSpeed);
        diff.Normalize();
        return diff * sourceSpeed;
    }

答案取决于您希望达到目标所需的时间。试试这两个公式

bullet distance = target distance + (target velocity * time)

bullet velocity * time = target distance + (target velocity * time)​

如果sourceSpeed 大于targetSpeed(targetVelocity 的大小),那么总是至少有一个解。如果 sourceSpeed 小于或等于 targetSpeed,则可能有也可能没有任何解。

您可以通过目标到达那里所需的时间 t 来参数化目标的路径。您想求解一个等式(结果是二次方程),以获得子弹到达那里所需的时间 (distance(t)/sourceSpeed) 与目标到达所需的时间 t 之间的相等性,以及只有非负 t 的解才有效。

distance(t) = magnitude(target + t*targetVelocity - source) 
            = sqrt((target.x-source.x + t*targetVelocity.x)^2 + (target.y-source.y + t*targetVelocity.y)^2)
            = sqrt(quadratic(t))

所以,你想解决

t = sqrt(quadratic(t))/sourceSpeed
t* sourceSpeed = sqrt(quadratic(t))
t^2 * sourceSpeed^2 = quadratic(t)

如果 t^2 项取消(当目标速度等于源速度时发生),您将得到一个线性方程(如果您尝试使用二次公式,它将给您除以 0)。否则,您会得到一个可以使用二次公式求解的二次方程,尽管您应该在尝试求平方根之前检查判别式 b^2-4ac 是否为负。如果判别式为负,则无解。只有非负实数解才能让你射中目标。

如果有两个正实数解,你必须选择一个。一旦你找到正确的 t 值,t_solution,你就知道目标将在哪里,(target + t_solution * targetVelocity),你可以从源头瞄准那个方向。