简体   繁体   中英

How to calculate the angle to shoot a bullet in order to hit a moving target?

I found one interesting project on that is requiring to calculate the angle to shoot a bullet in order to hit a moving object/target. There are five parameters that should be provided in this function. Here is the list of the arguments:

`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

For example if I provide set of parameters like this:

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

So far I was able to calculate the distance but I'm not sure if that is correct. Here is example:

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

}

Once I get the distance I should use speed of the bullet to get an angle. I'm trying to understand how this algorithm should work. I guess the distance between the target and the bullet should be calculated first then check if bullet reached the target. If anyone have an example or tips how this should be achieved please let me know. Thank you.

This problem is complicated but I will try to make a descriptive answer.

We need to establish some constants, like gravity (for now only gravity):

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

After establishing the need constants we will do the calculations.

=========== PART 1 ===========

First you need to know where your target is moving by using the Projectile Motion Formula.

Here are the need variables for the target:

`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

After that calculate the position of the target at time t .

在此输入图像描述
在此输入图像描述

Where:
Vx is the velocity along x-axis (You need to calculate this)
Vxo is the initial velocity along x-axis (the xVT )
Vy is the velocity along y-axis (You need to calculate this)
Vyo is the initial velocity along y-axis (the yVT )
g is the acceleration due to gravity
t is the time taken

Just start t at 1 then increment it. (Play with the initial value and increment to get the desired output)

=========== PART 2 ===========

After calculating the location of the target at time t , you then calculate the possible launch angle of the bullet given the position and speed if it can reach the position of the target at time t , if it can reach then the angle will be the answer, if not increment t

The needed variables for the bullet are:

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

The formula to calculate the angle is:
在此输入图像描述

Where :
v is initial launch speed (this is bulletS )
g is the gravity constant
x is the x position of the target at time t (this is xPT )
y is the y position of the target at time t (this is yPT )

=========== PART 3 ===========
Using the angle, speed, initial position of the bullet check if the bullet can reach the target's position at time t

The formula is:
在此输入图像描述
Where :
u is initial launch speed (this is bulletS )
g is the gravity constant
θ is the launch angle
Ux is initial x velocity of the bullet
Uy is initial y velocity of the bullet

After that calculate the position of the bullet at time t .

在此输入图像描述
在此输入图像描述
Where:
x is the x position of the bullet at time t
y is the y position of the bullet at time t
Vx is the velocity along x-axis (You need to calculate this)
Vxo is the initial velocity along x-axis (the Ux )
Vy is the velocity along y-axis (You need to calculate this)
Vyo is the initial velocity along y-axis (the Uy )
g is the acceleration due to gravity
t is the time taken
xPB - last known x position of the bullet
yPB - last known y position of the bullet

=========== PART 4 ===========
Now you have the need variables, which are:

`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

Compare the above variables, if xPB is equal to xPT and yPB is equal to yPT then the bullet will hit the target at time t and at launch angle θ . If not then increment time t and do Part 1 until Part 4 .

=========== SUMMARY ===========
This will be the flow of your program.

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

I hope you understand my explanation (I've spent a lot of time making it. Haha) But if you have any questions/clarifications, feel free to comment it.

Assuming the bullet will be fired from origin (0,0).

If the bullet meets the target after time t , then equation would be:

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

Now, If you solve it, you will get

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

Dividing equation 1 with equation 2 you get:

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

Now, if you assume m = sin(angle) , then cos(angle) = sqrt(1 - m * m)

So now, you have to solve the equation:

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

Move the term with square root on one side and the rest on other, so that you get a quadratic equation after squaring and you can solve that equation to get 2 valuee in terms of m = sin(angle)

So, the final angle is angle = arcsin(m)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM