I made this project to simulate a scenario of a anti-aircraft ballistic shooter The testing parameters are scaled down due to CPU performance
This document aims to explain three ballistic aiming techniques.
- Iterative
- Iterative RK4
- Analytical
View cone angle: 45 Degrees Max view distance: 6km Max shooting distance: 6km Shoot interval: 0.5s Max tolerance: 0.005 Iterations: 10000
Estimate the required velocity vector and use the Newton-Raphson refinement to correct the velocity error
FVector LaunchVelocity = (Displacement - 0.5f * Gravity * t * t) / t; Moving or accelerating targets, mid-range to long-range shots, realistic lead targeting
- Moderate CPU usage
- Good for moving targets
- Might fail at long distances
2000-3000m Distance
500-1200m Distance
Improve iterative acurracy using the Runge-Kutta integration
auto Acc = [&](const FVector& /*pos*/, const FVector& /*vel*/) -> FVector
{
return Acceleration; // constant gravity
};
FVector k1v = Acc(Position, Velocity);
FVector k1x = Velocity;
FVector k2v = Acc(Position + 0.5f * k1x * DeltaTime, Velocity + 0.5f * k1v * DeltaTime);
FVector k2x = Velocity + 0.5f * k1v * DeltaTime;
FVector k3v = Acc(Position + 0.5f * k2x * DeltaTime, Velocity + 0.5f * k2v * DeltaTime);
FVector k3x = Velocity + 0.5f * k2v * DeltaTime;
FVector k4v = Acc(Position + k3x * DeltaTime, Velocity + k3v * DeltaTime);
FVector k4x = Velocity + k3v * DeltaTime;
OutNewPosition = Position + (DeltaTime / 6.0f) * (k1x + 2.f * k2x + 2.f * k3x + k4x);
OutNewVelocity = Velocity + (DeltaTime / 6.0f) * (k1v + 2.f * k2v + 2.f * k3v + k4v);Very accurate prediction, compares the predicted impact point to the target predicted position.
Adjusts t until the simulated projectile matches the moving target with a tolerance
- More accurate curves
- Works well with gravity
- Might fail at long distances, but less than the normal iterative method
- Heavy CPU usage
- Sensitive to tolerance settings and time step
2000-3000m Distance
500-1200m Distance
Cheap computation of the launch angle
float SpeedSq = ProjectileSpeed * ProjectileSpeed;
float GravityMag = -GravityZ;
float Discriminant = SpeedSq * SpeedSq - GravityMag * (GravityMag * DistXZ * DistXZ + 2 * DeltaZ * SpeedSq);
float SqrtDisc = FMath::Sqrt(Discriminant);
float AngleNumerator = SpeedSq - SqrtDisc; // (or + for high arc)
float AngleDenominator = GravityMag * DistXZ;
float TanTheta = AngleNumerator / AngleDenominator;
float Theta = FMath::Atan(TanTheta);Static targets and known positions
- Acurate curves
- Cheap CPU usage
- Will fail at medium-long range
- Does not account for velocity or acceleration
2000-3000m Distance
500-1200m Distance
All 3 algorithms are good for different situations. The testing of this was very small and requieres more testing and different situations for more accurate results, but from the current testing we can deduce the following.
- The Iterative method is good at handling moving targets and it is cheap for the CPU to handle but has issues with its curve trajectory
- The RK4 Iterative method is good at handling moving target and its curve is way more accurate than the normal iterative method but requieres more CPU power
- The Analytical method is bad with moving targets and should be used for static targets and known positions, but is very cheap on the CPU
https://en.wikipedia.org/wiki/Projectile_motion
https://en.wikipedia.org/wiki/Newton%27s_method
https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods
https://gamedev.stackexchange.com/questions/53552/how-can-i-find-a-projectiles-launch-angle





