1
+ //All in world space! Gets point you have to aim to
2
+ //NOTE: this will break with infinite speed projectiles!
3
+ //https://gamedev.stackexchange.com/questions/149327/projectile-aim-prediction-with-acceleration
4
+ public static Vector3 GetTargetLeadingPositionQuadratic ( Vector3 launchPosition , Vector3 launcherVelocity , Vector3 projectileAcceleration , Vector3 targetPosition , Vector3 targetVelocity , Vector3 targetAcceleration , float distance , float projectileSpeed , int iterations )
5
+ {
6
+ Vector3 pT = targetPosition - launchPosition ;
7
+ Vector3 vT = targetVelocity - launcherVelocity ;
8
+ Vector3 aT = targetAcceleration ;
9
+ float s = projectileSpeed ;
10
+ Vector3 aP = projectileAcceleration ;
11
+
12
+ Vector3 accel = aT - aP ;
13
+
14
+ //time to target guess
15
+ float guess = distance / s ;
16
+
17
+ if ( iterations > 0 )
18
+ {
19
+ //quartic coefficients
20
+ float a = Vector3 . Dot ( accel , accel ) * 0.25f ;
21
+ float b = Vector3 . Dot ( accel , vT ) ;
22
+ float c = Vector3 . Dot ( accel , pT ) + Vector3 . Dot ( vT , vT ) - s * s ;
23
+ float d = 2f * Vector3 . Dot ( vT , pT ) ;
24
+ float e = Vector3 . Dot ( pT , pT ) ;
25
+
26
+ //solve with newton
27
+ float finalGuess = SolveQuarticNewton ( guess , iterations , a , b , c , d , e ) ;
28
+
29
+ //use first guess if negative or zero
30
+ if ( finalGuess > 0f )
31
+ {
32
+ guess = finalGuess ;
33
+ }
34
+ }
35
+
36
+ Vector3 travel = pT + vT * guess + 0.5f * aT * guess * guess ;
37
+
38
+ return launchPosition + travel ;
39
+ }
40
+
41
+ //All in world space! Gets launch velocity you have to aim to
42
+ //NOTE: this will break with infinite speed projectiles!
43
+ //https://gamedev.stackexchange.com/questions/149327/projectile-aim-prediction-with-acceleration
44
+ public static Vector3 GetTargetLeadingVelocityQuadratic ( Vector3 launchPosition , Vector3 launcherVelocity , Vector3 projectileAcceleration , Vector3 targetPosition , Vector3 targetVelocity , Vector3 targetAcceleration , float distance , float projectileSpeed , int iterations )
45
+ {
46
+ Vector3 pT = targetPosition - launchPosition ;
47
+ Vector3 vT = targetVelocity - launcherVelocity ;
48
+ Vector3 aT = targetAcceleration ;
49
+ float s = projectileSpeed ;
50
+ Vector3 aP = projectileAcceleration ;
51
+
52
+ Vector3 accel = aT - aP ;
53
+
54
+ //time to target guess
55
+ float guess = distance / s ;
56
+
57
+ if ( iterations > 0 )
58
+ {
59
+ //quartic coefficients
60
+ float a = Vector3 . Dot ( accel , accel ) * 0.25f ;
61
+ float b = Vector3 . Dot ( accel , vT ) ;
62
+ float c = Vector3 . Dot ( accel , pT ) + Vector3 . Dot ( vT , vT ) - s * s ;
63
+ float d = 2f * Vector3 . Dot ( vT , pT ) ;
64
+ float e = Vector3 . Dot ( pT , pT ) ;
65
+
66
+ //solve with newton
67
+ float finalGuess = SolveQuarticNewton ( guess , iterations , a , b , c , d , e ) ;
68
+
69
+ //use first guess if negative or zero
70
+ if ( finalGuess > 0f )
71
+ {
72
+ guess = finalGuess ;
73
+ }
74
+ }
75
+
76
+ Vector3 travel = pT + vT * guess + 0.5f * aT * guess * guess ;
77
+
78
+ Vector3 launchVelocity = travel / guess - 0.5f * aP * guess ;
79
+
80
+ return launchVelocity ;
81
+ }
82
+
83
+ static float SolveQuarticNewton ( float guess , int iterations , float a , float b , float c , float d , float e )
84
+ {
85
+ for ( int i = 0 ; i < iterations ; i ++ )
86
+ {
87
+ guess = guess - EvalQuartic ( guess , a , b , c , d , e ) / EvalQuarticDerivative ( guess , a , b , c , d ) ;
88
+ }
89
+ return guess ;
90
+ }
91
+
92
+ static float EvalQuartic ( float t , float a , float b , float c , float d , float e )
93
+ {
94
+ return a * t * t * t * t + b * t * t * t + c * t * t + d * t + e ;
95
+ }
96
+
97
+ static float EvalQuarticDerivative ( float t , float a , float b , float c , float d )
98
+ {
99
+ return 4f * a * t * t * t + 3f * b * t * t + 2f * c * t + d ;
100
+ }
0 commit comments