1
votes

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.

2
Will this project be a visual project or just to calculate the angle? Also there are many elements that can affect the angle, example is gravity. I have implemented this kind of problem before but not on a moving target. If you want I can give you the link to my GitHub projectMark Melgo
Generally just research about how to calculate trajectories/projectile.Mark Melgo
@Mark I should have the code to calculate the angle. Also the gravity should not be calculated in the equation. Please if you can I would like to see your example.espresso_coffee
My example is complicated, but just research about projectile. This kind of problem is complicated. But do you disregard all external forces? Example wind drag and gravity?Mark Melgo
Yes, I should disregard all external forces.espresso_coffee

2 Answers

4
votes

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.

enter image description here
enter image description here

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:
enter image description here

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:
enter image description here
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.

enter image description here
enter image description here
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.

1
votes

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)