3

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?

Mugen87
  • 28,829
  • 4
  • 27
  • 50
Sami
  • 341
  • 7
  • 22
  • Is your movement restricted to a single dimension, along one of the axes? – Berthur Apr 19 '21 at 12:22
  • yes only one axis – Sami Apr 19 '21 at 12:23
  • I suggest you take a look at the documentation for requestAnimationFrame, and how to properly make framerate-independent physics calculations using time delta. https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame Further, you should be able to keep just one variable velocity, which you update every frame after updating the displacement, multiplied with delta. Then, no table is required. – Berthur Apr 19 '21 at 12:33
  • Thanks for the suggestion, will take a look at it now. I also posted a new thread related to this, because I want to implement the equations directly in javascript https://stackoverflow.com/questions/67162136/implement-velocity-displacement-equations-in-javascript-in-a-loop-not-working – Sami Apr 19 '21 at 12:39

1 Answers1

3

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 );
Mugen87
  • 28,829
  • 4
  • 27
  • 50
  • when you say force is defined by an instance of THREE.Vector3 how to get the force and mass value in this case? I never used them before – Sami Apr 19 '21 at 09:20
  • Well, `mass` is something you define since for your objects (e.g. it could be 1 kg). The computation of a force mainly depends on the way your objects steer through 3D space. Assuming you have a target position, and just want to seek it, use something like https://github.com/Mugen87/yuka/blob/6314fd6f0297197f05342361d36fd5825c3b171e/src/steering/behaviors/SeekBehavior.js#L39-L57. – Mugen87 Apr 19 '21 at 10:01
  • given that I already have the acceleration values, do I still need the force and mass? can I just pass through the velocity.add().. – Sami Apr 19 '21 at 10:10
  • If it is a vector quantity, yes. – Mugen87 Apr 19 '21 at 10:22
  • I will try to figure something out from your example, I am still a beginner in three.js so things are not really too obvious for me, but ill dig deeper – Sami Apr 19 '21 at 12:24
  • Since this is a one-dimensional problem, the scalar acceleration value that he already has should be sufficient, should it not? I doubt force and mass are required. – Berthur Apr 19 '21 at 12:36
  • Acceleration is a vector quantity. It should be an instance of `Vector3` for correctness since he is operating in 3D space. Right now, he only defines the magnitude but not the direction. However, he can specify a unit vector representing the direction and then multiply the magnitude to get a proper acceleration vector. – Mugen87 Apr 19 '21 at 12:41