4
\$\begingroup\$

I'm making a game in which the goal is to get as many planets as possible to orbit around a star. The user launches planets at any distance away from the sun (as long as it's on-screen), and in any direction (possibly even directly at the sun, though their game won't last very long).

This means orbits can be circular, elliptical, or--more than likely--irregular, something like this:

https://gamedev.stackexchange.com/q/31007/15478

(Image originally from here)

The rules for my game that the player may launch planets as frequently as s/he likes...but they will only score a point for their first revolution (so spamming planets isn't likely to score very much).

Right now, the gravitational force is just F = ma (i.e. a constant force towards the sun). I'm trying to figure out when a planet in arbitrary orbit has completed a full revolution. This is how I'm doing it currently...

// If this planet is active...
Vector2 a = _body.position.normalized;
Vector2 b = (a + _body.velocity).normalized;

float angle = Vector2.Angle (a, b);
this._total_angle += angle * Time.deltaTime;

if (this._total_angle >= 360) {
    // If this planet has made a revolution...
    ++this._revolutions;
    this._total_angle = 0;
    this.OnRevolution.Invoke (this);
}

However, this is incorrect for anything besides circular orbits. No good.

Given all of this (and my near-total unfamiliarity with orbital mechanics), how can I tell when a planet in an arbitrary orbit has completed one full revolution?

EDIT: No, the planets will not affect each other's orbits (though they can collide into one another, but they'll just explode).

\$\endgroup\$
2
  • \$\begingroup\$ Just as a note, you won't get orbits like that with realistic Newtonian gravity -- although, if your planets can interact with each other, their orbits can certainly still get pretty weird. \$\endgroup\$ Dec 28, 2015 at 10:55
  • \$\begingroup\$ The image you gave is incorrect according to Kepler's Laws: en.wikipedia.org/wiki/Kepler's_laws_of_planetary_motion \$\endgroup\$ Dec 28, 2015 at 14:37

3 Answers 3

3
\$\begingroup\$

Assuming realistic Newtonian gravity (i.e. that the gravitational force between two bodies is inversely proportional to the square of their distance), and that the planets don't interact gravitationally with each other, but only with the sun, then the planets will always follow Kepler orbits (which, if closed, will always be elliptical).

Conversely, if the planets do affect each other via gravity, then you're dealing with the full n-body problem, which can have all sorts of crazy solutions like figure of 8 orbits or even planets accelerating to infinite velocities. Admittedly, those particular examples are mainly mathematical curiosities that you're unlikely to see in your game, but still, you should not expect there to be a single, unambiguous definition of an orbit for general n-body dynamics.

The best you can do is probably to just pick some arbitrary, pragmatic definition and stick to it. For example, in two dimensions, you could simply declare that a planet has completed a full orbit when its angle, as seen from the sun, equals the angle of its starting position (after actually looping around the sun). You could simply track this angle for each planet, adjusting it incrementally as the planet moves, and declaring a complete orbit when it hits ±360°; this way, you won't end up with false positives for planets that e.g. loop around each other and reverse direction without actually going around the sun.

If the above seems too easy, you could also require that the planet must return to approximately the same position and velocity as it had before. (Again, you'll probably want to also track the sun angle, to make sure that the planet has actually gone around the sun and not just, say, around another planet.) This probably requires you to track the trajectory of each planet (which, of course, you may want to do anyway for visualization purposes) and to come up with some fairly efficient scheme for finding near matches (e.g. using spatial binning).

\$\endgroup\$
1
\$\begingroup\$

Maybe the easiest approach would be to just create checkpoints. Seperate the space around the sun into, for example, 4 sectors:

  • -x, -y
  • +x, -y
  • +x, +y
  • -y, +y

Knowing the relative coordinates of the planet you can easily compute in which sector it currently is. You can assume the planet to have revoluted the sun once it has visited all four sectors.

\$\endgroup\$
0
\$\begingroup\$

Another approach may be considering max and min potential energy, or min and max orbit velocity on respect the sun:

enter image description here

Keep track of velocity maximum and velocity minimum.

If reached minimum velocity
 next time a minimum velocity is reached (maybe not the same minimum value) an  orbit has  occurred
end if

If reached maximum velocity
 next time a maximum velocity is reached (not the same maximum) an  orbit has  occurred
end if

Pros: you do not depend on angles and trajectories; suites for 2d and 3d

Cons : interaction with other bodies(planets) may generate false minimum and/or false maximum.

Cons 2 : orbit starts at a minimum or maximum and not when you release the planet

Final note resolving Cons2: when you reach min velocity (call it minP) and max velocity point (maxP) you can estimate semimajor axis (usualy called a ) as the sum of the distance from sun of minP and maxP divided by two.

a= (distance(sunP ,minP) + distance(sunP ,maxP))/2

enter image description here

So you can establish (aproximated) the orbital period as

\$ T = {2}{\pi}{\sqrt \frac{a^3}{\mu}} \$

where

\$ \mu = G * M \$

at this point when your time from planet release reaches T , you get one orbit.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .