๐ŸŒ Lesson 13: Earth-Moon-Sun Orbital Mechanics

Learn how celestial bodies move through space using pure mathematics

Trigonometry โ€ข Orbital periods โ€ข Interactive visualization

๐ŸŽฏ What You'll Learn

Mathematical Concepts:

  • Trigonometric functions (sin, cos)
  • Circular motion equations
  • Periodic functions and cycles
  • Coordinate transformations

Programming Skills:

  • Tkinter GUI programming
  • Animation and real-time graphics
  • Interactive controls and sliders
  • Mathematical modeling

๐ŸŒŒ Amazing Astronomical Facts

๐ŸŒ Earth's Orbit

Earth takes exactly 365.25 days to orbit the Sun at an average speed of 67,000 mph!

๐ŸŒ™ Moon's Orbit

The Moon orbits Earth every 27.3 days, creating the beautiful wavy pattern you'll see in the simulation.

๐Ÿ”ข The Math

In one Earth year, the Moon completes 13.4 orbits around Earth (365.25 รท 27.3 = 13.4).

๐ŸŽจ Epicycloid Pattern

The Moon's path creates a mathematical curve called an epicycloid - loops within loops!

๐Ÿš€ Try the Interactive Simulation

Experience the Earth-Moon-Sun system in action with our web-based simulation!

๐ŸŒ Launch Orbital Simulation

Use the show/hide controls to focus on different orbital components!

๐Ÿ’ป The Mathematics Behind the Magic

Here's how we calculate the positions using trigonometry:

# Earth's position around the Sun (circular orbit)
earth_angle = 2 * math.pi * day / 365.25  # Complete circle in 365.25 days
earth_x = AU * math.cos(earth_angle)      # X coordinate
earth_y = AU * math.sin(earth_angle)      # Y coordinate

# Moon's position relative to Earth
moon_angle = 2 * math.pi * day / 27.3     # Complete circle in 27.3 days
moon_x_rel = moon_radius * math.cos(moon_angle)
moon_y_rel = moon_radius * math.sin(moon_angle)

# Moon's absolute position (Earth + relative motion)
moon_x = earth_x + moon_x_rel
moon_y = earth_y + moon_y_rel

๐Ÿงฎ Key Mathematical Concepts:

  • 2ฯ€ radians = 360ยฐ - A complete circle
  • cos() and sin() - Convert angles to X,Y coordinates
  • Periodic motion - Repeating patterns over time
  • Coordinate addition - Combining Earth's motion + Moon's relative motion

๐Ÿš€ Advanced: Real Physics Simulation

Ready for the next level? This advanced version uses real gravitational physics with Newton's laws!

Advanced Features:

  • Real gravitational forces - F = Gร—mโ‚ร—mโ‚‚/rยฒ
  • Multiple planets - Earth, Mars, Jupiter with realistic masses
  • Interactive controls - Mouse wheel zoom, speed slider, pause/play
  • Orbital trails - See the beautiful paths planets take
import tkinter as tk
import math

class Planet:
    def __init__(self, name, color, radius, distance, mass, velocity):
        self.name = name
        self.color = color
        self.radius = radius
        self.distance = distance
        self.mass = mass
        self.x = distance
        self.y = 0
        self.vx = 0
        self.vy = velocity
        self.trail = []

class SolarSystemSim:
    def __init__(self, root):
        self.root = root
        self.root.title("Solar System Simulation")
        self.width = 900
        self.height = 850

        # ---- Layout ----
        self.main_frame = tk.Frame(root, bg="black")
        self.main_frame.pack(fill=tk.BOTH, expand=True)

        self.canvas = tk.Canvas(self.main_frame, bg="black", width=self.width, height=self.height)
        self.canvas.pack(fill=tk.BOTH, expand=True, side=tk.TOP)

        # Control frame stays visible
        control_frame = tk.Frame(root, bg="#222222", height=40)
        control_frame.pack(side=tk.BOTTOM, fill=tk.X)

        # ---- Physics ----
        self.G = 6.67430e-11  # Gravitational constant
        self.scale = 1.5e9    # Scale factor for display
        self.zoom_factor = 1.0
        self.time_step = 3600 * 12  # 12 hours per frame
        self.time_multiplier = 1.0

        # ---- Bodies ----
        self.sun = Planet("Sun", "yellow", 12, 0, 1.989e30, 0)
        self.earth = Planet("Earth", "deepskyblue", 6, 1.496e11, 5.972e24, 29783)
        self.mars = Planet("Mars", "orangered", 4, 2.279e11, 6.417e23, 24077)
        self.jupiter = Planet("Jupiter", "orange", 10, 7.785e11, 1.898e27, 13070)
        self.planets = [self.earth, self.mars, self.jupiter]
        self.running = True

        # ---- Controls ----
        self.reset_button = tk.Button(control_frame, text="Reset", command=self.reset, 
                                    bg="gray20", fg="white")
        self.reset_button.pack(side=tk.LEFT, padx=10, pady=5)

        tk.Label(control_frame, text="Simulation Speed:", fg="white", bg="#222222").pack(side=tk.LEFT, padx=5)
        self.speed_slider = tk.Scale(
            control_frame, from_=0.1, to=10, resolution=0.1, orient=tk.HORIZONTAL,
            length=200, command=self.update_speed, fg="white", bg="#222222",
            highlightthickness=0, troughcolor="gray30"
        )
        self.speed_slider.set(1.0)
        self.speed_slider.pack(side=tk.LEFT, padx=5, pady=2)

        # ---- Bindings ----
        self.root.bind("<space>", self.toggle_simulation)
        self.root.bind("<MouseWheel>", self.zoom)
        self.root.bind("<Button-4>", self.zoom)  # Linux scroll up
        self.root.bind("<Button-5>", self.zoom)  # Linux scroll down

        self.animate()

    # ----- Control Methods -----
    def toggle_simulation(self, event=None):
        self.running = not self.running

    def zoom(self, event):
        if event.delta > 0 or getattr(event, "num", 0) == 4:
            self.zoom_factor *= 1.1
        elif event.delta < 0 or getattr(event, "num", 0) == 5:
            self.zoom_factor /= 1.1
        self.scale = 1.5e9 / self.zoom_factor

    def reset(self):
        for p in self.planets:
            p.trail.clear()
            p.x = p.distance
            p.y = 0
            p.vx = 0
            if p.name == "Earth":
                p.vy = 29783
            elif p.name == "Mars":
                p.vy = 24077
            elif p.name == "Jupiter":
                p.vy = 13070
        self.running = True

    def update_speed(self, val):
        self.time_multiplier = float(val)

    # ----- Physics -----
    def update_positions(self):
        bodies = [self.sun] + self.planets
        dt = self.time_step * self.time_multiplier

        for p in self.planets:
            ax = ay = 0
            for other in bodies:
                if p == other:
                    continue
                dx = other.x - p.x
                dy = other.y - p.y
                r = math.sqrt(dx**2 + dy**2)
                a = self.G * other.mass / r**2  # Newton's law of gravitation
                ax += a * dx / r
                ay += a * dy / r

            p.vx += ax * dt  # Update velocity
            p.vy += ay * dt
            p.x += p.vx * dt  # Update position
            p.y += p.vy * dt
            p.trail.append((p.x, p.y))
            if len(p.trail) > 1500:
                p.trail.pop(0)

    # ----- Drawing -----
    def draw(self):
        self.canvas.delete("all")
        cx, cy = self.width / 2, self.height / 2
        # Draw Sun
        self.canvas.create_oval(cx - 12, cy - 12, cx + 12, cy + 12, fill="yellow")

        for p in self.planets:
            # Draw orbital trail
            for i in range(1, len(p.trail)):
                x1 = cx + p.trail[i-1][0] / self.scale
                y1 = cy + p.trail[i-1][1] / self.scale
                x2 = cx + p.trail[i][0] / self.scale
                y2 = cy + p.trail[i][1] / self.scale
                self.canvas.create_line(x1, y1, x2, y2, fill=p.color, width=1)

            # Draw planet
            x = cx + p.x / self.scale
            y = cy + p.y / self.scale
            self.canvas.create_oval(x - p.radius, y - p.radius, 
                                  x + p.radius, y + p.radius, fill=p.color)
            self.canvas.create_text(x + 15, y, text=p.name, fill=p.color, 
                                  font=("Arial", 10))

    def animate(self):
        if self.running:
            self.update_positions()
        self.draw()
        self.root.after(20, self.animate)  # 50 FPS

# Run the simulation
root = tk.Tk()
app = SolarSystemSim(root)
root.mainloop()

๐ŸŽฎ Controls:

  • Mouse Wheel: Zoom in/out
  • Spacebar: Pause/Resume
  • Speed Slider: Control time flow
  • Reset Button: Start over

๐Ÿงช Physics Concepts:

  • Newton's Law: F = Gร—mโ‚ร—mโ‚‚/rยฒ
  • Acceleration: a = F/m
  • Velocity Integration: v = vโ‚€ + aร—t
  • Position Integration: x = xโ‚€ + vร—t

๐Ÿ“ฅ Download & Code

Complete Python Program:

Download the full source code to run on your computer with Spyder!

๐Ÿ“ Download Python File

Requirements:

  • Python 3.7+ with tkinter
  • Anaconda/Spyder (recommended)
  • No additional libraries needed!
  • Works offline completely

๐Ÿ† Programming Challenges

Beginner Challenges:

  • Change the colors of Earth and Moon
  • Adjust the orbital speeds
  • Make the Sun bigger or smaller
  • Add a pause/play button

Advanced Challenges:

  • Add Mars with its own orbital period
  • Create elliptical orbits instead of circles
  • Add Jupiter's moons (Io, Europa, etc.)
  • Create a "view from Moon" perspective