Skip to main content
 首页 » 编程设计

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

2024年06月20日11qlqwjy

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

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

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

我一直在看数学,它一定是某种等式,函数有时可能会返回 false,即。子弹追不上目标,取决于targetVelocitysourceSpeed

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

另外,如果我能避免 Sqrt/Normalize 这对性能来说会很好,但我正在寻找相当简单/优雅的解决方案。

    /// 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; 
    } 

请您参考如下方法:

如果 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),并且您可以从源头瞄准那个方向。