找到击中移动目标的方向(移动目标射击子弹)

时间:2015-04-19 12:06:09

标签: c# math trigonometry algebra

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

我有 sourcePoint targetPoint 。目标有 targetVelocity (速度和方向),而来源有 sourceSpeed

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

我一直在看数学,它必须是某种方程式,其中函数有时可能会返回false,即。子弹无法赶上目标,具体取决于 targetVelocity sourceSpeed

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

另外,如果我可以避免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;
    }

2 个答案:

答案 0 :(得分:3)

如果sourceSpeed大于targetSpeed(targetVelocity的幅度),则始终至少有一个解决方案。如果sourceSpeed小于或等于targetSpeed,则可能有也可能没有任何解决方案。

您可以通过目标到达目标所需的时间来参数化目标的路径,t。你想要解决一个等式(事实证明是二次方程),以确定子弹到达那里所需的时间(距离(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),你可以从源头瞄准那个方向。

答案 1 :(得分:0)

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

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

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