How do I keep a body on a stable orbit?

I’m trying to simulate a solar system, but all the attempts I’ve made so far at keeping the bodies on a stable orbit have failed. The best I could come up with was this. The moon eventually crashes into the planet. Any ideas on how I could improve it?

maybe ou physic experts can help?
@Cedric / @RaananW

I would not simulate a planetary system with CannonJS. Don’t forget it’s a physics engine for game.
Precision is discarded in favor of speed.
I guess you can have some stable simulation with tweaks and many tries.
But, orbits are pretty easy to compute without a physics engine.

If you parent the moon to the Earth and then, set a local position like this:

moon.position = new BABYLIN.Vector3( Math.cos(day/28) * (Math.PI*2) * distanceEarthMoon, 0, Math.sin(day/28) * (Math.PI*2) * distanceEarthMoon);

Moreover, as this is fully procedural and deterministic, you could see your orbits at any date.

This is an old demo Schteppe once created. I just changed a few things and adjusted it to a newer version of babylon

You can read his answer here -

I’ve been looking at a similar type of scenario as yourself, @saathvik and have to echo the earlier comment about sacrificing precision for speed in these engines. I think that what you’re experiencing is that the physics engines don’t really conserve energy accurately in the system of forces at hand, perhaps with a side of floating point inaccuracies as well.

One subtle potential problem you’re facing is that your system’s particular combination of masses and orbital radii might preclude the existence of any stable orbits. In a 3-body system where there’s a central massive body being orbited in turn by less massive ones (m1 >>> m2 >>> m3), the Hill Sphere can give you a rough idea on where stable orbits may be found; truly long-term stable orbits can be found at roughly 1/2 to 1/3 of the Hs radius. Here’s a function I wrote to calculate this radius:

function hillSphereRadius() {
        let sM = 3 * this.starMass,
            mRat = this.mass / sM,
            cbMassRat = Math.cbrt(mRat),
            rH = this.orbitalRadius * cbMassRat;
        return rH;

One way to potentially solve this is to calculate where the body “should” be based solely on the bodies’ computed angular velocity and orbital radii, then periodically correct/update/compare positions with the physics engine. Another approach might be to ditch the physics engine completely and accumulate forces before changing the body positioning.

Here’s a function that I wrote to calculate the orbital speed and period of an object (assumes circular orbit, natch) given a primary mass, secondary mass, and orbital radius

function calculateAndSetOrbitalVelocity() {
        let g = GravityManager.GRAV_CONST,
            r = this.orbitalRadius,
            rCubed = Math.pow(r, 3),
            m = this._starMass,
            gM = g * m;

        this.orbitalSpeed = Math.sqrt((gM) / r);
        this.orbitalPeriod = Scalar.TwoPi * Math.sqrt(rCubed / gM);


Limited 3-body physics sample w/ planets on rails

This seems to work fine, but I found a simpler solution. I was thinking about what Cedric said:

I tried switching from CannonJs to AmmoJs and the moon is on a stable orbit after I remove the gravitational force of planet 2. Playground - .Maybe Cannon has an error, or Ammo is better suited for these kind of simulations :thinking:? I’ll try finding out why exactly Cannon isn’t working in this simulation :male_detective: . Though I must warn you that I’ll probably not find anything. I’m still a beginner :pensive: