Rodney Dunning's Home Page | Research and Scholarship | VPython | The Moon's Orbit


Introduction

The Moon orbits the Earth once every 29.53 days, while the latter orbits the Sun once every 365.24 days. It seems the Moon will pass between the Earth and Sun once per month, and that the Moon will enter the shadow of the Earth once per month--giving us one solar and one lunar eclipse each month. But in fact lunar and solar eclipses are much more rare. This is because the Moon's orbit is tilted by 5.5 degrees to the ecliptic, the plane of the Earth's orbit. For an eclipse to occur, the Moon must be in the ecliptic, and on a line that connects the Earth and Sun.  Or, alternatively, the Earth, Moon, and Sun must all be on the line of nodes, the line that connects the two points where the Moon's orbit crosses the ecliptic.

Description

The animation shows the Sun, Earth, Moon, the ecliptic plane, the line of nodes, and a line that traces the Moon's orbit. As the Earth orbits the Sun, the Moon orbits the Earth. The orbital frequencies are approximately correct, but several simplifications have been made to make the coding easier and to provide a convenient scale for viewing the animation:

Screen Shots

The Moon orbits the Earth, with its orbit tilted by 5.5 degrees to the ecliptic.
The Moon orbits the Earth as the Earth orbits the Sun. The green surface is the ecliptic plane. Half of the Moon's orbit is above the plane, and half below. The two points where the Moon's orbit intersects the ecliptic are called nodes. The line connecting the nodes is called the line of nodes.

The Moon's orbit seen from within the ecliptic plane.
Using the mouse, the user can rotate the point of view. In this image, we see the Moon's orbit from within the ecliptic plane. The tilt of the Moon's orbit relative to the plane is obvious.

Suggested Use

I've had success with the following steps in my introductory astronomy course:

  1. I first edit the code to zero-out the Moon's orbital inclination. See lines 40, 41 in the source code.
  2. I show the orbit to the class and ask them to determine how many lunar and solar eclipses per month are predicted by the model. They usually have no trouble seeing the model predicts two eclipses per month.
  3. After explaining to the class that lunar and solar eclipses are more rare, I edit the code to restore the Moon's orbital inclination. See lines 40, 41 of the source code.
  4. I show the animation again and ask the class to observe whether this model predicts that lunar and solar eclipses will occur more often, at the same frequency, or less often than the other model.
Hints:

Source Code

The source code appears between the bars below. Copy and paste the code into the Python IDLE environment, and hit F5 to run the code.


from visual import *
from __future__ import division

"""
    Rodney Dunning
    Longwood University


    An animation of the Moon's orbit about the Earth,
    as the later orbits the Sun.  The animation makes
    clear why we do not have a lunar and solar eclipse
    each month.

    Moon orbital parameters:

        a = 0.3844E+6 km
        e = 0.0549
        i = 5.145 degrees (relative to the ecliptic)
        T = 29.53 days (synodic)

    Earth orbital parameters:

        a = 149.6E+6 km
        e = 0.017
        i = 0 (definition)
        T = 365.23 days (synodic)

"""

#--------------------------------------------------
# Orbital parameters
#--------------------------------------------------

a = 1 # Earth semi-major axis
e = 0.017 # Earth eccentricity

ma = 0.0025695 # Moon semi-major axis
me = 0.0549 # Moon eccentricity

##i = -5.145 * pi /180 #inclination of the moon's orbit
i = 0 * pi /180 #inclination of the moon's orbit


#--------------------------------------------------
# Scene attributes and functions
#--------------------------------------------------

scene.title = "The Moon's orbit"
scene.x = 0
scene.y = 0
scene.width = 600
scene.height = 600
scene.range = (1.5*a*(1+e),1.5*a*(1+e),1.5*a*(1+e))
scene.autoscale = 0 ##0 means autoscaling is OFF
scene.userzoom = 1 ##0 means user cannot zoom
scene.userspin = 1 ##0 means user cannot spin
scene.lights = [vector(0,0,1)]
scene.ambient = 0.5
scene.label = label(visible=1,
                    pos=(0,0,0),
                    xoffset = 0,
                    yoffset = 0,
                    text = "The Moon's orbit--not to scale!\n"
                           "Click to begin.")
##scene.mouse_label = label(visible=1,
##                          pos=(0,100,0),
##                          text=("Mouse position"))

def return_mouse_pos(scene):
    scene.mouse_label.text = ("mouse\n x: %3.2f   y: %3.2f"
                              %(scene.mouse.pos.x, scene.mouse.pos.y))

def check_for_pause(scene): #checks for pause request
    if scene.mouse.clicked:
        scene.mouse.getclick()
        pause(scene)

def pause(scene):
    while 1:
##        return_mouse_pos(scene)
        if scene.mouse.clicked:
            scene.mouse.getclick()
            break

#---------------------------------------------------------
# Variables for keeping up with the elasped time
#---------------------------------------------------------

t = 0 # elapsed time
t_max = 20 # the Earth will complete ten full orbits

dt = 0.0005 

pi = arccos(-1.0)

fe = 1  # frequency of the Earth's orbit
fm = 12.368 # frequency of the Moon's orbit

#---------------------------------------------------------
# Create the Earth, Moon, and Sun
#---------------------------------------------------------

"""
    The sun is always centered in the animation window.

"""



sun = sphere(pos=vector(0,0,0),
             radius = 0.1*a,
             color = color.yellow)

earth_moon = frame(pos = vector(a,0,0))

print "earth_moon.axis= ",earth_moon.axis

earth = sphere(frame = earth_moon,
               pos=vector(0,0,0),
               radius = 0.05*a,
               color = color.blue,
               orbit = curve(color=color.white))

moon = sphere(frame = earth_moon,
              pos=vector(200*ma,0,0),
              radius= 0.03*a,
              color = color.white,
              orbit = curve(frame = earth_moon,
                            color=color.red))

ecliptic_plane = box(pos = sun.pos,
                     height = 3,
                     length = 3,
                     width = 0.001,
                     color = color.green)


line_of_nodes = box(pos = earth_moon.pos,
                    height = 0.01,
                    length = 1.25,
                    width = 0.01,
                    color = color.red,
                    axis  = (0,1,0))

#---------------------------------------------------------
# Animation
#---------------------------------------------------------

ready = 0
while not ready:
    ready = scene.mouse.getclick()
    scene.label.visible = 0
    scene.label.text = "Finished."

while t < t_max:
    rate(100)
    check_for_pause(scene)
    t += dt
    
    moon.pos.x = 150*ma*cos(2*pi*fm*t)
    moon.pos.y = 150*ma*sin(2*pi*fm*t)
    
    #Rotate the x,y postion of the moon

    x = moon.pos.x
    y = moon.pos.y

    moon.pos.x = x * cos(i)
    moon.pos.z = -x * sin(i)

    earth_moon.pos.x = a*cos(2*pi*fe*t)
    earth_moon.pos.y = a*sin(2*pi*fe*t)

    moon.orbit.append(pos=moon.pos)

    line_of_nodes.pos = earth_moon.pos

scene.label.visible = 1