[英]How to calculate the angle to shoot a bullet in order to hit a moving target?
我发现了一个有趣的项目就是需要计算射击子弹的角度以击中移动的物体/目标。 此功能应提供五个参数。 以下是参数列表:
`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;
}
}
一旦我到达距离,我应该使用子弹的速度来获得一个角度。 我试图了解这个算法应该如何工作。 我想应首先计算目标与子弹之间的距离,然后检查子弹是否到达目标。 如果有人有一个例子或提示如何实现这一点,请告诉我。 谢谢。
这个问题很复杂,但我会尝试做一个描述性的答案。
我们需要建立一些常数,比如引力(现在只有引力):
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
的位置。
哪里:
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
地点:
v
是初始启动速度(这是bulletS
)
g
是重力常数
x
是目标在时间t
的x位置(这是xPT
)
y
是目标在时间t
的y位置(这是yPT
)
===========第3部分===========
使用子弹的角度,速度,初始位置检查子弹是否能够在时间t
到达目标位置
公式是:
地点:
u
是初始发射速度(这是bulletS
)
g
是重力常数
θ
是发射角度
Ux
是子弹的初始x速度
Uy
是子弹的最初速度
之后计算子弹在时间t
的位置。
哪里:
x
是子弹在时间t
的x位置
y
是子弹在时间t
的y位置
Vx
是沿x轴的速度(你需要计算这个)
Vxo
是沿x轴的初始速度( Ux
)
Vy
是沿y轴的速度(你需要计算这个)
Vyo
是沿y轴的初始速度( Uy
)
g
是重力加速度
t
是时间
xPB
- 子弹的最后已知x位置
yPB
- 子弹的最后已知y位置
===========第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;
}
我希望你理解我的解释(我花了很多时间来做它。哈哈)但如果你有任何问题/澄清,请随意评论。
假设子弹将从原点(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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.