Public Sub Integrate2D(Obj As OBJECT2D, dt As Single, Integrator As CONST_INTEGRATOR)
Dim k1 As POINT2D, k2 As POINT2D, k3 As POINT2D, k4 As POINT2D
Dim l1 As VECTOR2D, l2 As VECTOR2D, l3 As VECTOR2D, l4 As VECTOR2D
With Obj
.Force.Net.X = .Mass * (Air_Resistance(0.5, AIR_DENSITY, 0.1, .Velocity.X))
.Force.Net.Y = .Mass * (-EARTH_GRAVITY + _
Air_Resistance(0.5, AIR_DENSITY, 0.1, .Velocity.Y))
.Acceleration.X = .Force.Net.X / .Mass
.Acceleration.Y = .Force.Net.Y / .Mass
Select Case Integrator
Case FORWARD_EULER
.Position.X = .Position.X + .Velocity.X * dt
.Velocity.X = .Velocity.X + .Acceleration.X * dt
.Position.Y = .Position.Y + .Velocity.Y * dt
.Velocity.Y = .Velocity.Y + .Acceleration.Y * dt
Case SECOND_ORDER_EULER
.Position.X = .Position.X + .Velocity.X * dt + 0.5 * .Acceleration.X * dt * dt
.Velocity.X = .Velocity.X + .Acceleration.X * dt
.Position.Y = .Position.Y + .Velocity.Y * dt + 0.5 * .Acceleration.Y * dt * dt
.Velocity.Y = .Velocity.Y + .Acceleration.Y * dt
Case VERLET
.Velocity.X = .Position.X - Old_Position.X + .Acceleration.X * dt * dt
Old_Position.X = .Position.X
.Position.X = .Position.X + .Velocity.X
.Velocity.Y = .Position.Y - Old_Position.Y + .Acceleration.Y * dt * dt
Old_Position.Y = .Position.Y
.Position.Y = .Position.Y + .Velocity.Y
Case VELOCITY_VERLET
Old_Acceleration.X = .Acceleration.X
.Position.X = .Position.X + .Velocity.X * dt + 0.5 * Old_Acceleration.X * dt * dt
.Velocity.X = .Velocity.X + 0.5 * (Old_Acceleration.X + .Acceleration.X) * dt
Old_Acceleration.Y = .Acceleration.Y
.Position.Y = .Position.Y + .Velocity.Y * dt + 0.5 * Old_Acceleration.Y * dt * dt
.Velocity.Y = .Velocity.Y + 0.5 * (Old_Acceleration.Y + .Acceleration.Y) * dt
Case SECOND_ORDER_RUNGE_KUTTA
k1.X = dt * .Velocity.X
k1.Y = dt * .Velocity.Y
l1.X = dt * .Acceleration.X
l1.Y = dt * .Acceleration.Y
k2.X = dt * (.Velocity.X + k1.X / 2)
k2.Y = dt * (.Velocity.Y + k1.Y / 2)
l2.X = dt * .Acceleration.X
l2.Y = dt * .Acceleration.Y
.Position.X = .Position.X + k2.X
.Position.Y = .Position.Y + k2.Y
.Velocity.X = .Velocity.X + l2.X
.Velocity.Y = .Velocity.Y + l2.Y
Case THIRD_ORDER_RUNGE_KUTTA
k1.X = dt * .Velocity.X
k1.Y = dt * .Velocity.Y
l1.X = dt * .Acceleration.X
l1.Y = dt * .Acceleration.Y
k2.X = dt * (.Velocity.X + k1.X / 2)
k2.Y = dt * (.Velocity.Y + k1.Y / 2)
l2.X = dt * .Acceleration.X
l2.Y = dt * .Acceleration.Y
k3.X = dt * (.Velocity.X - k1.X + 2 * k2.X)
k3.Y = dt * (.Velocity.Y - k1.Y + 2 * k2.Y)
l3.X = dt * .Acceleration.X
l3.Y = dt * .Acceleration.Y
.Position.X = .Position.X + k1.X * 1 / 6 + k2.X * 2 / 3 + k3.X * 1 / 6
.Position.Y = .Position.Y + k1.Y * 1 / 6 + k2.Y * 2 / 3 + k3.Y * 1 / 6
.Velocity.X = .Velocity.X + l1.X * 1 / 6 + l2.X * 2 / 3 + l3.X * 1 / 6
.Velocity.Y = .Velocity.Y + l1.Y * 1 / 6 + l2.Y * 2 / 3 + l3.Y * 1 / 6
Case FORTH_ORDER_RUNGE_KUTTA
k1.X = dt * .Velocity.X
k1.Y = dt * .Velocity.Y
l1.X = dt * .Acceleration.X
l1.Y = dt * .Acceleration.Y
k2.X = dt * (.Velocity.X + k1.X / 2)
k2.Y = dt * (.Velocity.Y + k1.Y / 2)
l2.X = dt * .Acceleration.X
l2.Y = dt * .Acceleration.Y
k3.X = dt * (.Velocity.X + k2.X / 2)
k3.Y = dt * (.Velocity.Y + k2.Y / 2)
l3.X = dt * .Acceleration.X
l3.Y = dt * .Acceleration.Y
k4.X = dt * (.Velocity.X + k3.X)
k4.Y = dt * (.Velocity.Y + k3.Y)
l4.X = dt * .Acceleration.X
l4.Y = dt * .Acceleration.Y
.Position.X = .Position.X + k1.X / 6 + k2.X / 3 + k3.X / 3 + k4.X / 6
.Position.Y = .Position.Y + k1.Y / 6 + k2.Y / 3 + k3.Y / 3 + k4.Y / 6
.Velocity.X = .Velocity.X + l1.X / 6 + l2.X / 3 + l3.X / 3 + l4.X / 6
.Velocity.Y = .Velocity.Y + l1.Y / 6 + l2.Y / 3 + l3.Y / 3 + l4.Y / 6
End Select
End With
End Sub