Search code examples
javascriptmathsimulationgame-physicsgravity

Create gravity using JavaScript


I am developing a physical sandbox. Each body has own properties like mass, velocity and acceleration. By default all bodies fall to the ground, but some of the them have gravitation field that can attract another bodies. I tried to calculate body's moving vectors and sum them, but it doesn't work. How can this attraction be correctly implemented?

class Body {
// Physical properties
  position = { x: 0, y: 0 }
  velocity = { x: 0, y: 0 }
  acceleration = { x: 0, y: 0 }
  mass = 1.0;
  gravity = 0.0;

// ... class constructord and etc.

  move = () => {
    if(this.checkCollision == true) return;
    this.setVelocityVector();
    this.position.y += this.velocity.y;
    this.position.x += this.velocity.x;
  }

  setVelocityVector = () => {
    // By default body falls down
    this.acceleration.y = this.mass * GRAVITY_ACCELERATION;

    // Check gravity body's attraction
    activeParticles.forEach(body => {
      if(body.gravity > 0) {
        // Calculate gravity power with Newton's formula:
        // F = G * m1 * m2 / r^2 
        var rr = (this.position.x - body.position.x) * (this.position.x - body.position.x) 
                 + (this.position.y - body.position.y) * (this.position.y - body.position.y);
        var a = body.gravity * this.mass * body.mass / rr;
        this.acceleration.x += a;
        this.acceleration.y += a;
      }
    });

    this.velocity.y += this.acceleration.y;
    this.velocity.x += this.acceleration.x;
  }
}

Solution

    1. As comments already pointed, you should calculate acceleration for all particles first, then move them.

    2. You are adding force to acceleration.

    3. You are calculating only amount of force, not it's direction. Here is correct (i think) version :

       var rr = (this.position.x - body.position.x) * (this.position.x - body.position.x) 
                + (this.position.y - body.position.y) * (this.position.y - body.position.y);
       var a = body.gravity * body.mass / rr;
       this.acceleration.x += (body.position.x - this.position.x) * a / sqrt(rr);
       this.acceleration.y += (body.position.y - this.position.y) * a / sqrt(rr);