Search code examples
javascriptthree.jsvelocityacceleration

How to compute velocity and displacement for a given acceleration in JavaScript?


I have a JSON file that has the acceleration value in m/s^2 and the timestamp. On the other end, I have a threeJS mesh that translate and rotate according to input value. Now I want to pass the velocity and displacement to the mesh to make it accelerate and decelerate and render these movement. Currently I compute the velocity and displacement and store them in an array, but in real-time setup I don't wanna store the value in an array to prevent memory overload, therefore, I only want to measure using the last acceleration reading. I am not sure if there is a JS API that can do the integration but I am trying to implement the formula below but it is not working as expected.

const previousVelocity = initialVelocity + ((currentAcceleration + previousAcceleration)/2)*(currentTime - previousTime)

const currentVelocity  = previousVelocity + ((currentAcceleration + previousAcceleration)/2)*(currentTime - previousTime)

const disp             = initialDisplacement + ((previousVelocity + currentVelocity)/2)*(currentTime - previousTime)

Below is a sample of my JSON file:

[
    {
        "time": 0,
        "acc": 0.11,
        "vel": 0,
        "disp": 0
    },
    {
        "time": 86400,
        "acc": 0.11,
        "vel": 0.11,
        "disp": 0.055
    },
    {
        "time": 172800,
        "acc": 0.11,
        "vel": 0.22,
        "disp": 0.22
    },
    {
        "time": 259200,
        "acc": 0.11,
        "vel": 0.33,
        "disp": 0.495
    },
    {
        "time": 345600,
        "acc": 0.35,
        "vel": 0.56,
        "disp": 0.9400000000000001
    }
]

and this is how I access the acceleration in the render function:

A bit more classification: Here I already computed the velocity and disp in excel before parsing them into the JSON file, but ideally I only wanna use the acceleration value and implement the formula in JS directly without storing anything in an array.

function render(dt) {
    dt *= 0.8 // in seconds
    time += dt
    while (data[currentIndex].time < time) {
        currentIndex++
        if (currentIndex >= data.length) return
    }
    console.log(currentIndex);
    const {acc,vel,disp} = data[currentIndex]

    document.querySelector("#disp").textContent = disp.toFixed(2);
    object.position.y = disp*0.07; // z for rightLeft, y for upDown

    var relativeCameraOffset = new THREE.Vector3 (5,0,0); // change camera offset
    var cameraOffset = relativeCameraOffset.applyMatrix4( object.matrixWorld );
    camera.position.x = cameraOffset.x;
    camera.position.y = cameraOffset.y;
    camera.position.z = cameraOffset.z;
    camera.lookAt( object.position );

    resizeToClient();
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}

How can I implement that in Javascript?


Solution

  • Usually, acceleration is derived from force and mass. Assuming the force is defined by an instance of THREE.Vector3, acceleration is computed via:

    acceleration.copy( force ).divideScalar( mass );
    

    Notice that acceleration is an instance of THREE.Vector3 since force is a vector quantity (it has a magnitude and direction).

    Given the acceleration, you can compute the velocity like so:

    velocity.add( acceleration.multiplyScalar( delta ) );
    

    The velocity is modulated over time with the acceleration. Since you compute this per simulation step, it's important to honor the amount of acceleration over a certain time frame (which is why you use the time delta value).

    In the next step, the displacement vector is computed and then added to the 3D object's position:

    displacement.copy( velocity ).multiplyScalar( delta );
    object.position.copy( displacement );