+1 vote

It's debateable whether this is a Godot question or just me making an embarrassing hash of high school physics...

I've got a basic Newtonian solar system sim with n-body gravity:

func _physics_process(delta):
    apply_gravity(delta)

func apply_gravity(delta):
    for p1 in planets:
        for p2 in planets:
            if p1 == p2:
                continue
            p1.velocity += newtonian_force(p1, p2) * delta

func newtonian_force(p1, p2):
    var r = p1.global_transform.origin.distance_to(p2.global_transform.origin)
    var dir = (p2.global_transform.origin - p1.global_transform.origin).normalized()
    if r < 1:
        return Vector3.ZERO
    return dir * G * p2.mass / (r*r)

The above works fine, I can spawn countless planets orbiting merrily around a sun. It's chaotic though.

So I want to make moons upon moons upon moons in circular orbits. So all I need to do is set the tangential velocity vector to make a stable orbit:

func set_orbital_velocity(parent_body):
    var dir = (parent_body.global_transform.origin - global_transform.origin).normalized().cross(Vector3.UP)
    var r = global_transform.origin.distance_to(parent_body.global_transform.origin)
    velocity += dir * sqrt(get_parent().G * parent_body.mass/r)

The parent_body is the object it's orbiting. So for a moon, I'll run this first sending the sun as an argument, then for the planet it's orbiting, etc, down the tree.

Except I don't get perfect orbits and I don't get why. Even with a simple 3-body problem.

Surely mass* v*v = (G * mass * parent_body.mass) / (r*r) mass cancels so v*v = (G * parent_body.mass) / r so to get vfor a circular orbit surely it's just: v = sqrt(G*parent_body.mass / r)

How does that not give me circular orbits?? I've tried staring indignantly at my screen but even that didn't fix it. ;)

Godot version 4.0 Alpha10
in Engine by (2,154 points)

maybe it helps

https://en.wikipedia.org/wiki/Orbital_mechanics

and
:):):):):):) :D
How does that not give me circular orbits?? I've tried staring indignantly at my screen but even that didn't fix it. ;)

And it had a section entitled "Circular Orbits" and instead of my:

v = sqrt(G*parent_body.mass / r)

It gave:

v = sqrt((2*G*parent_body.mass) / r)

Is it bad that I'm annoyed that when I tried it it worked perfectly?

You know this much better than I do. I just wrote it in case it helps.

If it works, no problem :)

Spoke too soon. I printed out the radius on a timer and it wasn't right after all. Funnily enough, when you click through to the full article for circular orbits on wikipedia it gives the exact formula I had to begin with. Wikipedia contradicting itself on basic orbital mechanics...

I've been trying it on a 2-body problem and the radius between them describes an ellipse. Not a massively eccentric but still.

First I thought bit precision (I'm sure that plays a role, G is tiny, M is huge) then the penny finally dropped... Kepler's 1st law of planetary motion.

When the planet goes round the sun, that accelerates too and describes a small circle. So perfectly circular orbits of the bodies relative to one another are impossible, it will always be an ellipse. The planet doesn't orbit the sun, they both orbit a common barycentre. That's been known since 1609 but I eventually caught up in 2022! I'm such a sausage.

Thanks for your help!

:) :) :) :)

what did you do my friend You will go towards subatomic particles

Two quick questions:

  1. Does it work for a 2 body system?
  2. What is the sun's parent body?

1:
It works with 2-body in the sense that they attract each other and make orbits; ditto n-body. In a 2-body system the orbital radius between the Sun and the Planet cannot be made constant. I eventually realised that this is just a result of Kepler's Laws and not a bug.

2:
The sun has no parent body. To be clear, in the Godot node sense they're all siblings in the node tree and exist in global space. They are not parents (that's to say their transform matrices are not multiplied meaning no body exists in the local space of another). I've just added them all to an array. With gravity every object is attracting every other object.

The "parent" thing is just me working out what the starting velocity should be to achieve an orbit. The sun is stationary to begin with so Vector3.ZERO. A planet has a velocity vector tangential to the sun. A moon has a velocity vector tangential to the planet plus its velocity tangential to the sun.

Only in this narrow sense of constructing a velocity vector that's applied once on start is the planet a "parent" of the moon. Otherwise they're identical objects but with varying mass.

Sorry if I confused with my wording.

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.