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.