The most important thing that is gonna be in our physics engine is the Integration class, which should be easy to code. It's gonna allow the user to choose an integration method, and will have a function to execute it. Some methods will be inaccurate and unstable, while others have their own pros and cons. It all depends on what you do. Like for example, Runge Kutta 4 would be perfect for spring simulations. While Runge Kutta methods (especially the higher order ones) are the most accurate and stable yet computationally expensive, Euler is the easiest to implement, yet is inaccurate and can easily become unstable. For future reference just incase I seem like I'm jumping the gun, here are some, which happen to be the most popular choices of integration methods:
x - Position
v - Velocity
a - Acceleration
dt - Delta Time Step Size
Euler
Aliases: Forward Euler, Explicit Euler
----------------------------------------
x = x + v * dt
v = v + a * dt
2nd Order Euler
----------------------------------------
x = x + v * dt + 0.5 * a * dt * dt
v = v + a * dt
Verlet
Aliases: Velocity-less Verlet
----------------------------------------
v = x - old_x + a * dt * dt
x = x + v
old_x = x
Time Corrected Velocity-less Verlet
----------------------------------------
v = (x - old_x) * (dt / old_dt) + a * dt * dt
x = x + v
old_x = x
old_dt = dt
Prescaled Euler
Aliases: Newton Stomer Verlet Variant
----------------------------------------
v = v + a * dt * dt
x = x + v
Re-ordered traditional Euler
Aliases: Semi-Implicit Euler, Newton Stormer Verlet, Backwards Euler
----------------------------------------
v = v + a * dt
x = x + v * dt
Velocity Verlet
----------------------------------------
x = x + v * dt + 0.5 * Old_A * dt * dt
v = v + 0.5 * (Old_A + a) * dt
Old_A = a
2nd Order Runge Kutta,
Aliases: Midpoint Method, RK2
----------------------------------------
k1 = dt * v
l1 = dt * a
k2 = dt * (v + k1 / 2)
l2 = dt * a
x = x + k2
v = v + l2
3rd Order Runge Kutta
Aliases: RK3
----------------------------------------
k1 = dt * v
l1 = dt * a
k2 = dt * (v + k1 / 2)
l2 = dt * a
k3 = dt * (v - k1 + 2 * k2)
l3 = dt * a
x = x + k1 * 1 / 6 + k2 * 2 / 3 + k3 * 1 / 6
v = v + l1 * 1 / 6 + l2 * 2 / 3 + l3 * 1 / 6
4th Order Runge Kutta
Aliases: RK4
----------------------------------------
k1 = dt * v
l1 = dt * a
k2 = dt * (v + k1 / 2)
l2 = dt * a
k3 = dt * (v + k2 / 2)
l3 = dt * a
k4 = dt * (v + k3)
l4 = dt * a
x = x + k1 / 6 + k2 / 3 + k3 / 3 + k4 / 6
v = v + l1 / 6 + l2 / 3 + l3 / 3 + l4 / 6
And here's some code examples, which show the results of each of them:
VB Code:
Option Explicit
-
Private Sub Form_Activate()
Dim k1 As Single, k2 As Single, k3 As Single, k4 As Single
Dim l1 As Single, l2 As Single, l3 As Single, l4 As Single
-
Dim x As Single, v As Single, a As Single
-
Dim dt As Single, dt2 As Single
Dim f As Single, m As Single
-
Dim old_x As Single, old_a As Single, old_dt As Single
-
Dim i As Long
-
a = 9.8
dt = 1 / 100
'List1.AddItem ""
List1.AddItem "Euler Integration"
List1.AddItem "---------------------"
-
x = 0
v = 0
For i = 0 To 99
x = x + v * dt
v = v + a * dt
List1.AddItem "X: " & x & " " & "V: " & v
Next i
List1.AddItem ""
List1.AddItem "2nd Order Euler Integration"
List1.AddItem "---------------------"
-
x = 0
v = 0
For i = 0 To 99
x = x + v * dt + 0.5 * a * dt * dt
v = v + a * dt
List1.AddItem "X: " & x & " " & "V: " & v
Next i
List1.AddItem ""
List1.AddItem "Newton Stormer Verlet (Semi Implicit Euler)"
List1.AddItem "---------------------"
-
x = 0
v = 0
For i = 0 To 99
v = v + a * dt
x = x + v * dt
List1.AddItem "X: " & x & " " & "V: " & v
Next i
List1.AddItem ""
List1.AddItem "Velocity-less Verlet Integration"
List1.AddItem "---------------------"
-
x = 0
v = 0
For i = 0 To 99
v = x - old_x + a * dt * dt
old_x = x
x = x + v
List1.AddItem "X: " & x & " " & "V: " & v / dt
Next i
List1.AddItem ""
List1.AddItem "Newton Stormer Verlet Variant Integration"
List1.AddItem "---------------------"
-
x = 0
v = 0
dt2 = dt * dt
For i = 0 To 99
v = v + a * dt2
x = x + v
List1.AddItem "X: " & x & " " & "V: " & v / dt
Next i
List1.AddItem ""
List1.AddItem "Velocity Verlet Integration"
List1.AddItem "---------------------"
-
x = 0
v = 0
old_a = a
For i = 0 To 99
x = x + v * dt + 0.5 * old_a * dt * dt
v = v + 0.5 * (old_a + a) * dt
old_a = a
List1.AddItem "X: " & x & " " & "V: " & v
Next i
List1.AddItem ""
List1.AddItem "Time Corrected Velocity-less Verlet Integration"
List1.AddItem "---------------------"
-
x = 0
v = 0
old_x = x
old_dt = dt
For i = 0 To 99
v = x - old_x * (dt / old_dt) + a * dt * dt
old_x = x
old_dt = dt
x = x + v
List1.AddItem "X: " & x & " " & "V: " & v / dt
Next i
-
List1.AddItem ""
List1.AddItem "RK2 Integration"
List1.AddItem "---------------------"
-
x = 0
v = 0
-
For i = 0 To 99
-
k1 = dt * v
l1 = dt * a
k2 = dt * (v + k1 / 2)
l2 = dt * a
x = x + k2
v = v + l2
List1.AddItem "X: " & x & " " & "V: " & v
-
Next i
List1.AddItem ""
List1.AddItem "RK3 Integration"
List1.AddItem "---------------------"
-
x = 0
v = 0
For i = 0 To 99
k1 = dt * v
l1 = dt * a
k2 = dt * (v + k1 / 2)
l2 = dt * a
k3 = dt * (v - k1 + 2 * k2)
l3 = dt * a
x = x + k1 * 1 / 6 + k2 * 2 / 3 + k3 * 1 / 6
v = v + l1 * 1 / 6 + l2 * 2 / 3 + l3 * 1 / 6
List1.AddItem "X: " & x & " " & "V: " & v
Next i
List1.AddItem ""
List1.AddItem "RK4 Integration"
List1.AddItem "---------------------"
-
x = 0
v = 0
-
For i = 0 To 99
-
k1 = dt * v
l1 = dt * a
k2 = dt * (v + k1 / 2)
l2 = dt * a
k3 = dt * (v + k2 / 2)
l3 = dt * a
k4 = dt * (v + k3)
l4 = dt * a
x = x + k1 / 6 + k2 / 3 + k3 / 3 + k4 / 6
v = v + l1 / 6 + l2 / 3 + l3 / 3 + l4 / 6
List1.AddItem "X: " & x & " " & "V: " & v
-
Next i
-
End Sub