Matt-the-Marxist
Matt-the-Marxist

Reputation: 174

Planetary physics are wonky

So in my physics class we're doing stuff with Kepler's law and other such equations. I figured I'd understand it better if i could make a model of it. and I've got it running... sorta. The motion of the planets, or moons in this instance, are supposed to be ellipses and they just aren't anywhere close.

I'm using actual masses, distances, and speeds for the planetoids so I'm not sure whats going wrong

let G = 6.67408*Math.pow(10,-11)
let scl = 4000
let mars;
let phobos;
let deimos;

function setup() {
	createCanvas(600, 600)
	mars = new Planet(0, 0, 0, 0, 6.4171*pow(10,24))
	phobos = new Planet(-9234420, 0, 0, -2138 , 1.0659*pow(10,16))
	deimos = new Planet(23463200, 0, 0, 1351.3, 1.4762*pow(10,15))
	background(0)
}

function draw() {
	translate(width/2-mars.pos.x/scl, height/2-mars.pos.y/scl)
	background(0, 1)
	for(let i=0;i<10;i++){
		mars.show()
		phobos.show()
		deimos.show()
		mars.update()
		phobos.update()
		deimos.update()
		grav(phobos, mars)
		grav(mars, deimos)
		grav(phobos, deimos)
		
		if(deimos.pos.dist(mars.pos)/scl>(width/2)){
			scl = deimos.pos.dist(phobos.pos)/(0.99*width/2);
			background(0)
		}
		
	}
}

function force(p1, p2){
	d = p1.pos.dist(p2.pos)
	f = G*(p1.mass*p2.mass)/(d*d)
	return f
}

function grav(p1,p2){
	d1 = p2.pos.copy().sub(p1.pos).normalize()
	d2 = p1.pos.copy().sub(p2.pos).normalize()

	f = force(p1,p2)
	
	p1.acc.add(d1.mult(force/p1.mass))
	p2.acc.add(d2.mult(force/p2.mass))
}

function Planet(x, y, vx, vy, mass){
	this.mass = mass;
	this.pos = createVector(x, y)
	this.vel = createVector(vx, vy)
	this.acc = createVector(0, 0)
	
	this.show = function(){
		stroke(255)
		strokeWeight(width/100)
		point(this.pos.x/scl, this.pos.y/scl)
	}
	
	this.update = function(){
		this.pos = this.pos.add(this.vel);
		this.vel = this.vel.add(this.acc)
		this.acc = this.acc.mult(0)
	}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"></script>

as i said one would think that they would have elliptical orbits yet they're not. so I'm just at a loss.

Upvotes: 2

Views: 80

Answers (1)

Charlie Wallace
Charlie Wallace

Reputation: 1830

To make the physics work in this code we need to make a couple of corrections.

The grav function needs to calculate force and use it to update acceleration, however, there is a mistake that causes the force function to be used instead of the calculated force and the original code multiplies by NaN instead of force/mass as the force function is not a number.

function grav(p1,p2){
  d1 = p2.pos.copy().sub(p1.pos).normalize()
  d2 = p1.pos.copy().sub(p2.pos).normalize()

  f = force(p1,p2) // we need to store the calculated force
  p1.acc.add(d1.mult(f/(p1.mass))) // and use it here
  p2.acc.add(d2.mult(f/(p2.mass))) // and here
}

The code also needs to call update after each call to the grav function:

grav(phobos, mars);
mars.update();
phobos.update();

grav(mars, deimos);
mars.update();
deimos.update();

grav(phobos, deimos);
phobos.update();
deimos.update();

let G = 6.67408*Math.pow(10,-11)
let scl = 4000
let mars;
let phobos;
let deimos;

function setup() {
  createCanvas(600, 600);
  mars = new Planet(0, 0, 0, 0, 6.4171*pow(10,24));
  phobos = new Planet(-9234420, 0, 0, -2138 , 1.0659*pow(10,16));
  deimos = new Planet(23463200, 0, 0, 1351.3, 1.4762*pow(10,15));
  background(0);
}

function draw() {
  translate(width/2-mars.pos.x/scl, height/2-mars.pos.y/scl);
  background(0, 1);
  for(let i=0;i<10;i++){
    mars.show();
    phobos.show();
    deimos.show();

    grav(phobos, mars);
    mars.update();
    phobos.update();

    grav(mars, deimos);
    mars.update();
    deimos.update();
    
    grav(phobos, deimos);
    phobos.update();
    deimos.update();
    
    if(deimos.pos.dist(mars.pos)/scl>(width/2)){
      scl = deimos.pos.dist(phobos.pos)/(0.99*width/2);
      background(0)
   }
  }
}

function force(p1, p2){
	d = p1.pos.dist(p2.pos)
	f = G*(p1.mass*p2.mass)/(d*d)
	return f
}

function grav(p1,p2){
  let d1 = p2.pos.copy().sub(p1.pos).normalize()
  let d2 = p1.pos.copy().sub(p2.pos).normalize()

  let f = force(p1,p2)
  p1.acc.add(d1.mult(f/(p1.mass)))
  p2.acc.add(d2.mult(f/(p2.mass)))
}

function Planet(x, y, vx, vy, mass){
  this.mass = mass;
  this.pos = createVector(x, y)
  this.vel = createVector(vx, vy)
  this.acc = createVector(0, 0)

  this.show = function(){
    stroke(255)
    strokeWeight(width/100)
    point(this.pos.x/scl, this.pos.y/scl)
  }

  this.update = function(){
    this.pos = this.pos.add(this.vel);
    this.vel = this.vel.add(this.acc)
    this.acc = this.acc.mult(0)
  }
}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>

With these corrections we get roughly elliptical orbits, however, after a few revolutions the moons drift away from Mars. This is not surprising as all of the initial conditions and the value of G are approximations.

Upvotes: 1

Related Questions