Simulating Gravity accurately

Hello!

I'm relatively new to p5.js, and have been working on a physics simulation where I want to accurately simulate gravity in a window that allows for scaling units.

The problem I had was scaling such that I could set my gravity.y vector to 9.8, and have 1 meter = 1 pixel, such that the object accelerates down at 9.8px/x^2. However, at a frameRate of 60, there's problems. I discovered that I had to do G.mult(someFactor) to make it accurate. Here's the formula that made it work:

function fS(n) {
  total = 0;
  for (var i = 0; i <= n; i++) {
    total += i;  
  }
  return 1/(total*2);
}        

someFactor = fS( frameRate() );

I also have a simScale variable that changes the meters/pixels ratio, and currently it's messing up the physics i.e it only produces the right outputs when its equal to 1 (1m = 1px). Here's the entire code, looking for suggestions as to how to improve.

=======================================

function fS(n) {
  total = 0;
  for (var i = 0; i <= n; i++) {
    total += i;  
  }
  return 1/(total*2);
}

function setup() {
  counter = 0;
  fR = 60;
  frameRate(fR);
  W = windowWidth;
  H = windowHeight;
  ground = H;
  simScale = 1;
  frameScale = fS(fR);
  G = createVector(0, 9.8);
  G.mult(simScale);


  createCanvas(W, H);
  ball = new Ball();
}

function draw() {
  background(2);
  ball.show();
  counter++;
}


function Ball() {

  this.r = 10; 

  this.dropHeight = 123    // height in meters you want to drop from

  this.initHeight = ground - this.dropHeight - this.r; 
  this.pos = createVector(0, this.initHeight / simScale);
  this.acceleration = createVector(0, 0);
  this.velocity = createVector(0, 0);
  this.altitude = ground - this.pos.y - this.r;

  this.updatePos = function() {
    var scaledG = p5.Vector.mult(G, frameScale); 
    this.acceleration.add(scaledG);  
    this.velocity.add(this.acceleration);
    this.pos.add(this.velocity);
    if (this.pos.y > ground - this.r) {  
      this.pos.y = ground - this.r;  
      noLoop();
    }
    this.altitude = ground - this.pos.y - this.r;
    this.acceleration.mult(0); 
  }

  this.show = function() {
    this.updatePos();
    ellipse(W/2, this.pos.y, this.r*2, this.r*2); 
    fill(200);
    text("Scale: 1m = " + simScale + " px(s)", 200, 30);
    text("Altitude: " + (this.altitude/simScale).toFixed(2) + " m", 20, 30);
    text("Elapsed: " + (counter/fR).toFixed(2) + " s", 20, 50);
    text("Displacement: " + Math.abs(this.initHeight - this.pos.y).toFixed(2) + " m", 20, 70);
    text("Velocity: " + (this.velocity.y * fR).toFixed(2) + " m/s", 20, 90);  
  }

}
Tagged:

Answers

Sign In or Register to comment.