如何计算射出子弹以击中移动目标的角度?

时间:2019-02-28 02:14:27

标签: javascript java

我发现了一个有趣的项目,该项目需要计算射击子弹的角度才能击中移动的物体/目标。此功能应提供五个参数。这是参数列表:

`xP` - last known x position of the target
`yP` - last known y position of the target
`xV` - last known x velocity of the target
`yV` - last known y velocity of the target
`bulletS` - the speed of the bullet

例如,如果我提供这样的参数集:

xP yP xV yV bulletS
5  5  0  1    3
4  4  1  0    2
5  5  0  -1   3

到目前为止,我已经能够计算出距离,但是我不确定这是否正确。这是示例:

import java.lang.*;

public class Problem2 {

    public static void main(String[] args) {
        // Function takes arguments from the parameters table.
        System.out.println(calculateShotAngle(10,10,1,0,2));

    }

    static double calculateShotAngle(float xP, float yP, float xV, float yV, float pSpeed) {
        // Function equation to calculate distance
        double distance =  Math.pow(Math.sqrt(Math.pow((xV-xP),2) + Math.pow((yV-yP), 2)),2);

        return distance;
    }

}

一旦我获得了距离,我应该使用子弹的速度来获得一个角度。我试图了解此算法应如何工作。我猜应该先计算目标和子弹之间的距离,然后检查子弹是否到达目标。如果有人有示例或提示应如何实现,请告诉我。谢谢。

2 个答案:

答案 0 :(得分:2)

这个问题很复杂,但我会尽一个描述性的答案。

我们需要建立一些常数,例如引力(目前仅引力):

double gravity = 0.98;
// Add more constants if needed

建立需求常数后,我们将进行计算。

===========第1部分===========

首先,您需要使用“弹丸运动公式”来了解目标的移动方向。

以下是目标的需求变量:

`xPT` - last known x position of the target
`yPT` - last known y position of the target
`xVT` - last known x velocity of the target
`yVT` - last known y velocity of the target

之后,计算目标在t时间的位置。

enter image description here
enter image description here

位置:
Vx是沿x轴的速度(您需要对此进行计算)
Vxo是沿x轴的初始速度(xVT
Vy是沿y轴的速度(您需要对此进行计算)
Vyo是沿y轴的初始速度(yVT
g是由于重力引起的加速度
t是花费的时间

只需将t从1开始,然后将其递增即可。 (播放初始值并递增以获得所需的输出)

===========第2部分===========

在时间t计算目标位置之后,如果在时间t可以到达目标位置,则给定位置和速度,然后计算子弹的可能发射角,如果可以达到,那么角度将成为答案,如果不增加t

项目符号所需的变量是:

`xPB` - last known x position of the bullet
`yPB` - last known y position of the bullet
`bulletS` - the speed of the bullet

计算角度的公式为:
enter image description here

其中:
v是初始启动速度(这是bulletS
g是重力常数
x是目标t在目标的x位置(这是xPT
y是目标t的y位置(这是yPT

===========第3部分===========
使用子弹的角度,速度和初始位置,检查子弹是否可以在时间t到达目标位置

公式为:
enter image description here
其中:
u是初始启动速度(这是bulletS
g是重力常数
θ是发射角度
Ux是子弹的初始x速度
Uy是子弹的初始y速度

之后,计算时间t的子弹位置。

enter image description here
enter image description here
其中:
x是时间t处项目符号的x位置
y是子弹在时间t上的y位置
Vx是沿x轴的速度(您需要对此进行计算)
Vxo是沿x轴的初始速度(Ux
Vy是沿y轴的速度(您需要对此进行计算)
Vyo是沿y轴的初始速度(Uy
g是由于重力引起的加速度
t是花费的时间
xPB-子弹的最后一个x位置
yPB-子弹的最后一个已知位置

===========第4部分===========
现在,您需要的变量是:

`xPB` - last known x position of the bullet
`yPB` - last known y position of the bullet
`xPT` - last known x position of the target
`yPT` - last known y position of the target

比较以上变量,如果xPB等于xPT并且yPB等于yPT,则子弹将在时间t击中目标并以发射角θ。如果不是,则增加时间t并执行第1部分,直到第4部分

===========摘要==========
这就是程序的流程。

static double calculateShotAngle(
    double xPT, double yPT, double xVT, double yVT,
    double xPB, double yPB, double bulletS) {
    double gravity = 0.98;
    double angle = null;
    double time = 1; // change this value if needed (try smaller increments if after a single increment the bullet's position will pass the target's position)
    double xPTOriginal = xPt; // Save the initial x position of target
    double yPTOriginal = yPt; // Save the initial y position of target


    while (true) {
        // do Part 1;
        // do Part 2;
        // do Part 3;
        // below code is Part 4
        if (hasBeenHit(xPT, yPT, xPB, yPB)) {
            break;
        } else {
            t++; // increment t
            // Revert the initial position of target
            xPt = xPTOriginal;
            yPt = yPTOriginal;
        }
    }

    return angle;
}

// Method used to check if bullet hits the target
// Method assumes that bullet and target only occupies a point (1 of axis x and 1 of axis y)
static boolean hasBeenHit(double xPT, double yPT, double xPB, double yPB) {
    return xPT == xPB && yPT == yPB;
}

希望您能理解我的解释(我已经花了很多时间。哈哈)但是,如果您有任何疑问/澄清,请随时发表评论。

答案 1 :(得分:1)

假设子弹将从原点(0,0)发射。

如果子弹在时间t之后到达目标,则等式为:

(xP + xV * t, yP + yV * t) = ((bullets * t) * cos(angle), (bullets * t) * sin(angle))

现在,如果您解决了,您将会得到

xP = (bullets * cos(angle) - xV) * t /* equation 1 */
yP = (bullets * sin(angle) - yV) * t /* equation 2 */

将等式1与等式2相除得到:

xP * sin(angle) - yP * sin(angle) = (xP * yV - xV * yP) / bullets

现在,如果您假设m = sin(angle),那么cos(angle) = sqrt(1 - m * m)

所以现在,您必须求解方程:

xP * m - yP * sqrt(1 - m * m) = (xP * yV - xV * yP) / bullets

移动项的一侧为平方根,另一侧为平方根,以便在平方后得到一个二次方程,您可以求解该方程,以m = sin(angle)的形式得到2个值。

因此,最终角度为angle = arcsin(m)