Mathematics Stack Exchange is a question and answer site for people studying math at any level and professionals in related fields. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to emulate planetary rotation. I have a 'planet' rotating around the 'sun', but when trying to rotate the 'moon' around the 'planet', the motion is skewed.

If I stop the motion of the 'planet', the rotation is fine. I think this is just outside of my understanding.

I have demo at

share|cite|improve this question
up vote 5 down vote accepted

Wow, that's a pretty neat effect! What's happening is this:

  1. First, you rotate the moon around the planet by some angle, say, $\alpha$.
  2. Then you rotate the planet around the sun by some angle, say, $\beta$.
  3. Now, you try to rotate the moon around the planet by angle $\alpha$ again... but the planet has moved in the mean time!

Thus, you get the effect seen in your demo: the absolute velocity of the moon is proportional to its distance from the planet, so when the moon is close, it's moving slower than the planet and so lags behind. But that puts it further away from the planet, and so makes it move faster, so it catches up again — but then its orbit takes it in front of the planet, so that their trajectories converge and they move closer again. Thus, you end up with these spirograph-like trajectories.

Varying the ratio $\alpha/\beta$ changes the trajectory; $\alpha/\beta > 1$ gives effects similar to what you observed, while if $\alpha/\beta = 1$, the moon escapes to infinity and never comes back. For $0 < \alpha/\beta < 1$, the planet actually catches up to the moon after completing one extra rotation around the sun, while $\alpha/\beta < 0$ causes the moon to dip inwards closer to the sun (and, for $-1 < \alpha/\beta < 0$, to trace neat quasi-polygonal patterns as it does so).

Anyway, the fix is pretty simple: after rotating the planet around the sun, also rotate the moon around the sun by the same angle (jsFiddle):

function do_rotation() {
    moon.attr(rotate(get_point(moon), get_point(earth), 5));
    earth.attr(rotate(get_point(earth), get_point(sun), 1));
    moon.attr(rotate(get_point(moon), get_point(sun), 1));  // <- NEW

    setTimeout(do_rotation, 1000 / 60);

That way, the planet and the moon stay at the same distance from each other. As a side effect, the rotation speed of the moon around the planet, from a non-rotating viewpoint, becomes $\alpha + \beta$ instead of just $\alpha$. If you don't want that, just subtract the rotation angle of the planet from that of the moon.

share|cite|improve this answer
Thank you so much, that's brilliant, and thank you for explaining it too! :) – Adam Burton Jul 5 '12 at 22:12

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.