I am writing an aimbot script for my AI, I am a bit confused about how to get the vertical projectile motion formulas to help me find the time and initial velocity required to fire the projectile at so it hits its target, For the target, I have its velocity and vertical displacement, I thought a Quadratic formula to find the intersection of its displacement over time intersecting with the projectiles displacement over time would be the solution but now I am stuck because I am missing the initial velocity as well as the time, Any help would be appreciated :)
CodePudding user response:
Orient your coordinate plane such that the y-axis is up/down from your perspective, and the z-axis passes through you and your target ( being towards the target). We do not care about x. Center the origin on you.
We need to first talk about finding the time it takes a projectile to travel from you to the target. Assuming there's no air drag, the projectile will move at a constant velocity along the z axis (it may accelerate along the y-axis, however). This gives us:
df_pz = a_pz * t**2 / 2 vi_pz * t di_pz
df_pz : final displacement - projectile's z component
di_pz : initial displacement - projectile's z component
a_pz : acceleration - projectile's z component
vi_pz : initial velocity - projectile's z component
t : time
If we assume there's no air resistance, a_pz
is zero, and since the origin is centered on you, di_pz
is zero. That leaves:
df_pz = vi_pz * t
We know df_pz
is the distance to the target along the z-axis, and can solve for time t
for the projectile to travel there. t
will be defined in terms of vi_pz
, which is fine.
Now, lets talk about your target's motion. Your target will follow a trajectory:
df_ty = a_ty * t**2 / 2 vi_ty * t di_ty
df_ty : final displacement - target's y component
di_ty : initial displacement - target's y component
a_ty : acceleration - target's y component
vi_ty : initial velocity - target's y component
t : time
We know t
however (or, have an equation we can substitute in anyways), so we can plug in and solve for the final displacement (in terms of vi_pz
).
With the df_ty
value, we can now determine the initial y velocity of the projectile. We'll be using a similar formula:
df_py = a_py * t**2 / 2 vi_py * t di_py
df_py : final displacement - projectile's y component
di_py : initial displacement - projectile's y component
a_py : acceleration - projectile's y component
vi_py : initial velocity - projectile's y component
t : time
We have time t
, the a_py
may or may not be equal to a_ty
, depending on the game engine, but I'll assume you know that value regardless. We know di_py
is zero since we're centered at the origin. That just leaves vi_py
and df_py
. Since we want to intercept the target, df_py
equals df_ty
.
We then plug in those values and solve for vi_py
. This gives us the initial velocity of the projectile along the y axis, in terms of vi_pz
.
Now, with this newest equation, we'll actually solve for vi_py
and vi_pz
. Take the equation:
|V|**2 = vi_py**2 vi_pz**2
|V| - magnitude of the initial velocity vector
The value |V|
should be constant for any shot (assuming you can't "charge" you shot to shoot the projectile faster / further).
Take whatever this value is, substitute the value for vi_py
(defined in terms of vi_pz
) and solve for vi_pz
. This will give you a concrete value for vi_pz
. Take this, plug it back into the equation for vi_py
, and obtain a concrete value for vi_py
. Do the same for t
.
Now, there may be one issue- df_ty
we used earlier may be wrong. If df_ty
is so low that it places the target below the ground, we need to clamp it to ground-level. Plug in vi_pz
and check. This is just a simple if statement, I won't be writing a formula for this. You do need to know what y coordinate is "ground-level" below the target.
If this happens, also recompute a new vi_py
, vi_pz
, and t
using this new df_ty
. The process will be much the same, except you already have a concrete value for df_ty
now, so you can skip the part involving |V|
to get vi_py
.
And there you have it: vi_py
, vi_pz
, and t
- the velocity and time necessary to intercept the target. You may have to take this one step further and calculate the angle to shoot at, which would just be arctan(vi_py/vi_pz)
.
CodePudding user response:
Finding the time tmin where the missile and target are at the closest approach is fairly straightforward.
Consider at the time of launch t=0 the target missile is at the origin, with an initial velocity vector v and being tracked as a function of time as
p(t) = v t 0.5 g t2
where g is the gravity vector (usually pointing downwards).
At the time of launch, the target is at position vector o, moving with velocity vector u and being tracked over time with
r(t) = o u t 0.5 g t2
The time of minimum distance is
tmin = (o·(v-u)) / ((v-u)·(v-u))
Here · is the vector dot product and it results in a number.So both the numerator and denominators are numbers.
The closest approach distance is
dmin = √( (o·o) - (o·(v-u))2 / ((v-u)·(v-u)) )
The next part is harder. To optimize the problem, in order to make the minimum distance zero, and find the velocity vector that fits the constraints (max. speed, or time to impact).
The insight here is that the launch velocity vector must be on the plane defined by the target velocity vector and gravity. The simplest approach here is to employ a numerical method to estimate the minimum distance as a function of the launch angle if the launch speed is fixed.
There is an analytical solution here but is very complex and it depends on some assumptions.
Furthermore, once the optimal trajectory is found, you can play around to see which launch speed works best. With some random testing I did I noticed the required speed at the optimal angle as a function of a delay from detection jumps to a really high value at some point, and then gradually decreases. I suppose this corresponds to the time the target is mostly overhead. Optimally you want to detect the target as early as possible.