- #1
Manuel Goucha
- 9
- 0
Hi, I'm trying to calculate a postion and velocity of a body over time using an integrator at each time step, I've only used simple integrators so far but I wanted to a better one that I've seen, RK4 - Runge–Kutta method, to calculate new values of position equation.
I've been using the simple SUVAT and euler method:
a = F/m
v = v0 + a*dt
x = x0 + v0*dt + 0.5*a*dt*dt
but this gives me bad results when needing high precision with few iterations, that's why, using RK4, I can get better results with fewer iterations of an amount of calculues leaving more free cpu.
my problem is that I don't know how to apply Runge–Kutta metthod to a 3 equation physics system, because Runge–Kutta algorithm only uses v and x, so how can I adapt it to my system?
I have this algorithm:
and the RK4 algotithm I'm trying to use:
but this doens't work, and it doesn't gives me any change at the Acceleration over time, I can't find any better informations on this on the internet and cna't find a way to implement like the first system example, where I give 3 variables - Pos, Vel, Acc, and 2 known values, Force and Mass
I really apreciate any help solving this
I've been using the simple SUVAT and euler method:
a = F/m
v = v0 + a*dt
x = x0 + v0*dt + 0.5*a*dt*dt
but this gives me bad results when needing high precision with few iterations, that's why, using RK4, I can get better results with fewer iterations of an amount of calculues leaving more free cpu.
my problem is that I don't know how to apply Runge–Kutta metthod to a 3 equation physics system, because Runge–Kutta algorithm only uses v and x, so how can I adapt it to my system?
I have this algorithm:
Code:
EulerIntegrate(Pos, Vel, Acc, For, Mass, dt: Double);
var
MDiv1: TValue;
DTDiv: TValue;
i: Integer;
begin
Pos := Pos + (Vel * dt);
Vel := Vel + (Acc * dt);
Acc := Acc + F / M;
end;
and the RK4 algotithm I'm trying to use:
Code:
RK4Integrate(var Pos, Vel, Acc, dt: double);
type
State = record
Pos: TVect2; // position
Vel: TVect2; // velocity
end;
Derivative = record
DPos: TVect2; // derivative of position: velocity
DVel: TVect2; // derivative of velocity: acceleration
end;
function Evaluate(Initial: State; Acc, dt: Double; D: Derivative): Derivative;
var
State: State;
Output: Derivative;
begin
State.Pos := Initial.Pos + D.DPos * DT;
State.Vel := Initial.Vel + D.DVel * DT;
Output.DPos := State.Vel;
Output.DVel := Acc;
Result := Output;
end;
procedure Integrate(var State: State; Acc, dt: Double);
var
A, B, C, D: Derivative;
NewDerivative: Derivative;
DXDT, DVDT: Double;
begin
A := Evaluate(State, Acc, 0, NewDerivative);
B := Evaluate(State, Acc, DT*0.5, a);
C := Evaluate(State, Acc, DT*0.5, b);
D := Evaluate(State, Acc, DT, c);
DXDT := (A.DPos + ((B.DPos + C.DPos)* 2) + D.DPos) * 1/6;
DVDT := (A.DVel + ((B.DVel + C.DVel)* 2) + D.DVel) * 1/6;
State.Pos := (State.Pos + DXDT) * DT;
State.Vel := (State.Vel + DVDT) * DT;
end;
var
Start: State;
Derivate: Derivative;
begin
Start.Pos := P;
Start.Vel := V;
Integrate(Start, A, DT);
P := Start.Pos;
V := Start.Vel;
end;
but this doens't work, and it doesn't gives me any change at the Acceleration over time, I can't find any better informations on this on the internet and cna't find a way to implement like the first system example, where I give 3 variables - Pos, Vel, Acc, and 2 known values, Force and Mass
I really apreciate any help solving this