I've just started dabbling with code, and as a learning exercise I've written a simple algorithm for solving gravitational n-body problems numerically in JavaScript.
I would be very grateful for general feedback as far as the quality of the code goes (first time I'm asking somebody to review my code; I'm very shy about it!), and more specifically advise on how I could optimize it as when I implement the algorithm in THREE.js in the shape of a simulation of the solar system the simulation starts lagging when I include more than around 70 bodies in the simulation. I know n-body algorithms are computationally intensive by nature, especially those of the brute force variety, but I'm pretty sure I've missed out on some useful tricks that would push it a bit further.
Update: to see a working example of the code, check out the jsfiddle I have thrown together https://jsfiddle.net/e9t88dwh
function nBodyProblem(parameters) {
this.g = parameters.g; //Gravitational constant
this.law = parameters.law; //Force law, inverse-square in our universe
this.dt = parameters.dt; //Time step to be used
this.masses = parameters.masses; //Object array with initial conditions for the bodiess to be simulated
}
nBodyProblem.prototype = {
constructor: nBodyProblem,
getDistance: function (m1, m2) {
return Math.pow((m1.x - m2.x) * (m1.x - m2.x) + (m1.y - m2.y) * (m1.y - m2.y) + (m1.z - m2.z) * (m1.z - m2.z), this.law);
},
updatePositionVectors: function () {
for (var i = 0, len = this.masses.length; i < len; i++) {
this.masses[i].x += this.masses[i].vx * this.dt;
this.masses[i].y += this.masses[i].vy * this.dt;
this.masses[i].z += this.masses[i].vz * this.dt;
}
return this;
},
updateVelocityVectors: function () {
var forceVectorX = 0;
var forceVectorY = 0;
var forceVectorZ = 0;
for (var i = 0, ilen = this.masses.length; i < ilen; i++) {
for (var j = 0, jlen = this.masses.length; j < jlen; j++) {
//We don't want to calculate self gravity!!!!!
if (i !== j) {
forceVectorX += (this.g * this.masses[j].m) * (this.masses[j].x - this.masses[i].x) / this.getDistance(this.masses[i], this.masses[j]);
forceVectorY += (this.g * this.masses[j].m) * (this.masses[j].y - this.masses[i].y) / this.getDistance(this.masses[i], this.masses[j]);
forceVectorZ += (this.g * this.masses[j].m) * (this.masses[j].z - this.masses[i].z) / this.getDistance(this.masses[i], this.masses[j]);
}
}
this.masses[i].vx += forceVectorX * this.dt;
this.masses[i].vy += forceVectorY * this.dt;
this.masses[i].vz += forceVectorZ * this.dt;
forceVectorX = 0;
forceVectorY = 0;
forceVectorZ = 0;
}
return this;
}
};