This problem has nothing to do with float vs double precision. float has more than enough precision for this, and actually Processing uses a float for everyone by default, so any double values you are trying to use will simply be lost.
All your problems are caused by this line:
for (Planet p: planets) { mv.add(p.speed.mult(p.mass)); }
In particular, this bit:
p.speed.mult(p.mass)
This line multiplies each planet’s speed by its mass.
You might think that p.speed.mult(p.mass) will leave the original p.speed PVector unchanged, but it is not. PVector not immutable, so calling the mult() function changes the underlying instance of PVector .
Your first two planets have mass of 1 , so this line does not affect them. But your third planet has mass of 10 , which means that you multiply your speed by 10 for every single frame.
You can verify this by simply changing the mass of one of your original planets to 10 or even 2 , or by changing the mass of the third planet to 1 .
So, to fix your main problem, just get rid of this line or change it so that it does not change p.speed PVector .
Further information can be found in the processing link for PVector#mult() :
Multiplies a vector by a scalar. The version of the method that uses float acts directly on the vector on which it is called (as in the first example above). The versions that receive both the PVector and the float, since the arguments are static methods, and each returns a new PVector i.e. the result of a multiplication operation.
Basically, you can change this line as follows:
PVector.mult(p.speed, p.mass)
This will leave p.speed unchanged and return a copy with the multiplied value.
Taking a step back, you will have another problem, because your planets can be arbitrarily close to each other. In other words, their distance can approach (or equal to) zero. This does not happen in real life, and if so, you can bet that everything will go crazy. This way you will have crazy “gravity” if everything is too close. You can limit their distances.
If you have additional questions, it will be easier for you to help you if you are working with this MCVE and not publishing the whole project:
PVector planetOneLocation = new PVector(300, 200); PVector planetOneSpeed = new PVector(0, -.1); float planetOneMass = 1; PVector planetTwoLocation = new PVector(100, 200); PVector planetTwoSpeed = new PVector(0, .1); float planetTwoMass = 10; float g = 5; void setup() { size(500, 500); } void draw() { updatePlanetOne(); updatePlanetTwo(); planetOneLocation.add(planetOneSpeed); planetTwoLocation.add(planetTwoSpeed); background(0); ellipse(planetOneLocation.x, planetOneLocation.y, 10*planetOneMass, 10*planetOneMass); ellipse(planetTwoLocation.x, planetTwoLocation.y, 10*planetTwoMass, 10*planetTwoMass); } void updatePlanetOne() { PVector accDir = PVector.sub(planetTwoLocation, planetOneLocation); float a = g * planetOneMass / (accDir.mag() * accDir.mag()); accDir.normalize(); PVector acceleration = accDir.mult(a); planetOneSpeed.add(acceleration); } void updatePlanetTwo() { PVector accDir = PVector.sub(planetOneLocation, planetTwoLocation); float a = g * planetTwoMass / (accDir.mag() * accDir.mag()); accDir.normalize(); PVector acceleration = accDir.mult(a); planetTwoSpeed.add(acceleration); }