# Newtonian orbital velocity

Attention Topic was automatically imported from the old Question2Answer platform.

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 `v`for 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.

Two quick questions:

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

PoisonIvy | 2022-07-15 15:02

maybe it helps

Orbital mechanics - Wikipedia

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

ramazan | 2022-07-14 09:44

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

ramazan | 2022-07-14 10:19

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.

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

ramazan | 2022-07-14 13:30

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.