Make sure you understand the tutorial and the previous integration lab before doing this lab.

In the last lab, you implemented position update integration. Try simulating a ball under the effect of gravity by adding the following line to the start of your script, and then using "Clear Scene and Run". If you don't have your code on hand, you can find it below.

add_body(#{pos: vec(0, 0), accel: vec(0, 9.81)});

In this lab, we'll implement velocity update, making this scene work.

Position-Update Review

The following code implements position-update integration. Make sure you understand it.

// disables engine integration,
// so you can reimplement it yourself
set_integration(false);

// the update function is called every frame,
// `ids` is a list of every body in the simulation
let update = |ids, bodies| {
    // This for loop runs over every body in the simulation
    for id in ids {
        // grab the relevant info about the body
        let x_0 = id.get_pos();
        let v_0 = id.get_vel();
        let dt = DT();

        // the position update equation
        let x_f = x_0 + v_0 * dt;

        // tell the engine to update the body's position
        id.set_pos(x_f);
    }
}

Velocity-Update

The velocity update equation is:

v_f = v_0 + a * dt

Use this equation and the code from earlier to write a velocity update script:

set_integration(false);

add_body(#{pos: vec(0, 0), accel: vec(0.0, -0.1), radius: 50.0});

let update = |ids, bodies| {
    for ?? {
        let x_0 = id.get_pos();
        let v_0 = id.get_vel();
        let a_0 = id.get_accel();
        let dt = DT();

        let x_f = ??
        let v_f = ??

        id.set_pos(x_f);
        id.set_vel(??);
    }
}

If you've done it correctly, the ball should fall, accelerating down.


To check that this behavior is exactly what we expect, let's run an experiment. Update your code to fit the following snippet:

set_integration(false);

add_body(...);

let t = 0.0;
let update = |ids, bodies| {
    if (is_paused()) {
        return;
    }
    if (t >= 300.0) {
        set_paused(true);
    }

    for ... {
        ...
    }

    t += DT();
}

Don't worry if you don't understand the added code. Its purpose it to keep track of the time and pause the simulation after about 5 seconds.


Now, calculate the expected position and velocity of the ball by hand. Note that the simulation's time does not match up with the real world.

  • Delta Time: 300 seconds

  • Start Position: 0.0 meters

  • Start Velocity: 0.0 m/s

  • Start Acceleration: -0.1 m/s²

  • End position: ??

  • End Velocity: ??

Click the body in the simulation. Does its velocity and position match what you calculated?

The velocity should match up exactly, but it is expected that the position will be a little different than calculated. This is because of computational integration error; we are essentially taking a Riemann sum with non-zero width rectangles. Numerical integration is an advanced topic that won't be covered in this class. If you're interested, read about it on Wikipedia.