Skip to content

Commit

Permalink
Evolving system in fixed timesteps
Browse files Browse the repository at this point in the history
  • Loading branch information
ftripier committed Sep 1, 2018
1 parent f798e62 commit 87f001f
Showing 1 changed file with 21 additions and 13 deletions.
34 changes: 21 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,26 +99,17 @@ function draw(state: State, ctx: CanvasRenderingContext2D) {
const INITIAL_ANGULAR_VELOCITY = Math.PI * (1 / 128);
const INITIAL_THETA = 0;

function update(state: State) {
if (state.system.theta == null) {
state.system.theta = INITIAL_THETA;
}
if (state.system.angularVelocity == null) {
state.system.angularVelocity = INITIAL_ANGULAR_VELOCITY;
}
function evolveSystem(state: State, dt: number) {
const gravity = 0.001;
const mass = 1;
const gravitationalAcceleration = -gravity * Math.sin(state.system.theta);

const normalizedDt = state.dt / (16 + 2 / 3);
const oldTheta = state.system.theta;
const oldAngularVelocity = state.system.angularVelocity;
let newTheta = oldTheta + oldAngularVelocity * normalizedDt;
let newAngularVelocity =
oldAngularVelocity + gravitationalAcceleration * normalizedDt;
let newTheta = oldTheta + oldAngularVelocity * dt;
let newAngularVelocity = oldAngularVelocity + gravitationalAcceleration * dt;

// because of floating point error and because we don't evolve the system at fixed timesteps,
// the energy of the system rises over time.
// because of floating point error, the energy of the system rises over time.
// This corrects for these errors.
const potentialEnergy = (gravity: number, mass: number, theta: number) =>
-gravity * mass * Math.cos(theta);
Expand All @@ -145,6 +136,23 @@ function update(state: State) {
}
}

function update(state: State) {
if (state.system.theta == null) {
state.system.theta = INITIAL_THETA;
}
if (state.system.angularVelocity == null) {
state.system.angularVelocity = INITIAL_ANGULAR_VELOCITY;
}

let dt = state.dt;
while (dt > 0) {
const expectedFrameTime = 16 + 2 / 3;
const normalizedDt = Math.max(dt, expectedFrameTime) / expectedFrameTime;
evolveSystem(state, normalizedDt);
dt -= expectedFrameTime;
}
}

const loop = (state: State, ctx: CanvasRenderingContext2D) => {
update(state);
draw(state, ctx);
Expand Down

0 comments on commit 87f001f

Please sign in to comment.