๐ 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 SimulationUse 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 FileRequirements:
- 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