Skip to main content
Computer Science Solar System Validated

Solar System

Orbital mechanics simulation of our cosmic neighborhood

Presets

Inner System
Mercury, Venus, Earth, Mars
Outer System
Jupiter, Saturn, Uranus, Neptune, Pluto

Planets

Controls

© 2013 - 2026 Cylian 🤖 Claude
Instructions Claude

Prompt utilisé pour régénérer cette page :

Page: Solar System - Orbital Mechanics Simulation
Title: "Solar System"
Description: "Orbital mechanics simulation of our cosmic neighborhood"
Icon: earth
Tags: physics, simulation, solar-system, astronomy
Status: validated
Category: computer-science
Front matter: js: default (no scss key — uses default convention)

HTML structure in index.md:
  <section class="container visual size-1000 ratio-1-1 canvas-contain">
    <canvas id="simulation-canvas"></canvas>
  </section>

Widget files:
  _presets.left.md (weight: 5, title: "Presets"):
    ### Presets
    div#preset-list.preset-list with 2 preset items:
      div.preset-item[data-preset="inner"]: .title "Inner System" + .desc "Mercury, Venus, Earth, Mars"
      div.preset-item[data-preset="outer"]: .title "Outer System" + .desc "Jupiter, Saturn, Uranus, Neptune, Pluto"

  _planets.left.md (weight: 10, title: "Planets"):
    ### Planets
    div#planet-list (font-size 0.8rem, monospace) — populated dynamically by JS

  _controls.right.md (weight: 10, title: "Controls"):
    ### Controls
    Checkbox: <input type="checkbox" id="show-trails" checked> "Show trails"
    Speed slider: <input type="range" id="speed-slider" min="0.1" max="2" step="0.1" value="0.5"> with <span id="speed-value">0.5</span>
    Button group (flex, gap 0.5rem, center, margin-top 1rem):
      {{< button id="btn-play" label="Pause" >}}
      {{< button id="btn-reset" label="Reset" >}}

Architecture (4 JS files):
  default.js — Main orchestrator (IIFE, ES module imports):
    Imports: Body from ./_physics-body.lib.js, VerletEngine from ./_physics-verlet.lib.js, { PRESETS, SOLAR_SYSTEM } from ./_presets.lib.js, panic from /_lib/panic_v3.js
    CONFIG: width=1000, height=1000, dt=0.5, tickInterval=16, trailFade=0.985
    State: canvas, ctx, bodies[], engine (VerletEngine), running, tickTimer, trailCanvas, trailCtx, currentPreset='inner'
    DOM elements: canvas (#simulation-canvas), btnPlay (#btn-play), btnReset (#btn-reset), presetList (#preset-list), showTrails (#show-trails), speedSlider (#speed-slider), speedValue (#speed-value), planetList (#planet-list)

    createSolarSystem(): Creates bodies from SOLAR_SYSTEM data filtered by current preset
      - Sun: fixed at center (cx=500, cy=500), mass=sunMass from preset, color=#FDB813, visualRadius=15
      - Sun has body.fixed=true, body.fixedX=cx, body.fixedY=cy
      - Planets: positioned on positive x-axis (x = cx + distance*distanceScale, y = cy)
      - Orbital velocity: v = sqrt(sunMass / distance), applied as vy (perpendicular to radius)
      - Each planet gets name, visualRadius, mass, color from SOLAR_SYSTEM data

    initCanvas(): Sets canvas.width/height = CONFIG.width/height (1000x1000, NO devicePixelRatio scaling)
    initTrailCanvas(): Creates offscreen canvas (document.createElement), same dimensions, gets 2d context
    reset(): stop(), recreate bodies, new VerletEngine, clear trail canvas, initCanvas, render, panic.info

    Simulation control:
      start(): Sets running=true, updates button text to "Pause", adds .is-running class, starts setInterval(tick, 16ms)
      stop(): Sets running=false, button text "Play", removes .is-running, clearInterval
      toggle(): Calls start() or stop() based on running state
      tick(): Reads dt from speedSlider value (or CONFIG.dt fallback), calls engine.step(bodies, dt), resets fixed bodies (x=fixedX, y=fixedY, vx=vy=0), calls render()

    Trail system:
      drawTrails(): Skips if !showTrails.checked. Fades existing trails via destination-out compositing (globalAlpha = 1 - 0.985 = 0.015). Draws 1px arc circles at each body position (skips Sun)
      Trail canvas drawn beneath main canvas each frame via ctx.drawImage(trailCanvas, 0, 0)

    Rendering:
      render(): Calls drawTrails if checked, clears main canvas (transparent), draws trailCanvas, iterates bodies:
        Sun: radial gradient glow (color -> color+'80' -> 'transparent', radius = visualRadius*2)
        All bodies: filled circle at visualRadius, name label below (#888, 10px monospace, center-aligned, y + radius + 12)
      Calls updatePlanetList() after each render

    updatePlanetList(): Builds inline HTML for each body — color dot (10px circle), name, distance from sun in AU (calculated as sqrt(dx²+dy²) / preset.distanceScale, displayed with 2 decimals)

    switchPreset(presetName): Validates preset exists, sets currentPreset, calls updatePresetList(), reset()
    updatePresetList(): Toggles .is-active class on [data-preset] elements matching currentPreset

    Event handlers:
      btnPlay click → toggle()
      btnReset click → reset()
      speedSlider input → updates speedValue textContent with 1 decimal
      presetList click → event delegation on closest [data-preset], calls switchPreset()

    Init sequence: initTrailCanvas(), updatePresetList(), reset(), panic.notice. NO auto-start — waits for Play click

  _physics-body.lib.js — Body class (ES module, default export):
    constructor(x, y, vx, vy, mass, color='#fff'): Position, velocity, mass, color. Acceleration ax/ay=0. Trail array, maxTrail=500
    recordTrail(): Pushes {x,y}, shifts if > maxTrail
    clearTrail(): Resets trail=[]
    Additional properties set externally: name, visualRadius, fixed, fixedX, fixedY

  _physics-verlet.lib.js — VerletEngine class (ES module, default export):
    Constants: G=1.0, SOFTENING=0.5
    constructor(options={}): this.g (default G), this.softening (default SOFTENING), this._initialized=false
    calculateAcceleration(body, bodies): N-body gravitational force. distSq = dx²+dy²+softening², accel = G*other.mass/distSq, direction normalized by dist. Returns {ax,ay}
    initialize(bodies): Computes initial accelerations for all bodies, sets _initialized=true
    step(bodies, dt): Velocity Verlet integration (3-step):
      1. x(t+dt) = x(t) + v*dt + 0.5*a*dt² (position update)
      2. Calculate new accelerations at new positions (stores old accelerations)
      3. v(t+dt) = v(t) + 0.5*(a_old + a_new)*dt (velocity update with average acceleration)
      Records trail for each body after velocity update
    Energy methods: kineticEnergy (0.5*m*v²), potentialEnergy (-G*m1*m2/r for all pairs), totalEnergy (KE+PE)
    reset(): Sets _initialized=false

  _presets.lib.js — Presets and solar system data (ES module, named exports):
    PRESETS object with 2 entries:
      inner: name "Inner System (Telluric)", distanceScale=315, sunMass=3330, planets=['Mercury','Venus','Earth','Mars']
      outer: name "Outer System (Gas Giants)", distanceScale=12, sunMass=3330, planets=['Jupiter','Saturn','Uranus','Neptune','Pluto']
    SOLAR_SYSTEM object:
      sun: name='Sun', distance=0, mass=333000, radius=15, color='#FDB813'
      planets array (9 entries, distance in AU, mass relative to Earth scaled down 100x):
        Mercury: distance=0.387, mass=0.00055, radius=3, color=#B5B5B5
        Venus: distance=0.723, mass=0.00815, radius=5, color=#E6C87A
        Earth: distance=1.0, mass=0.01, radius=5, color=#6B93D6
        Mars: distance=1.524, mass=0.00107, radius=4, color=#C1440E
        Jupiter: distance=5.203, mass=3.178, radius=12, color=#D4A574
        Saturn: distance=9.537, mass=0.952, radius=10, color=#F4D59E
        Uranus: distance=19.19, mass=0.145, radius=7, color=#B5E3E3
        Neptune: distance=30.07, mass=0.171, radius=7, color=#5B7FDE
        Pluto: distance=39.48, mass=0.000022, radius=3, color=#C9B8A0
    Exported as: export { PRESETS, SOLAR_SYSTEM }

default.scss:
  .preset-list: flex column, gap 0.5rem
  .preset-item: padding 0.75rem, background var(--background-color-surface), border 1px solid var(--draw-color-surface), border-radius 0.5rem, cursor pointer, transition border-color 200ms
    &:hover: border-color var(--draw-color-primary)
    &.is-active: border-color var(--draw-color-primary), background var(--background-color-primary)
    .title: font-weight bold, 0.9rem, margin-bottom 0.25rem
    .desc: font-size 0.75rem, color #888

Important implementation notes:
  - Canvas fixed 1000x1000 (NO devicePixelRatio scaling)
  - Simulation loop is setInterval-based (16ms tick), NOT requestAnimationFrame
  - No auto-start — simulation waits for user to click Play
  - Sun is fixed at center: body.fixed=true, position reset to fixedX/fixedY each tick
  - Speed slider value is used directly as dt in engine.step() (range 0.1-2.0)
  - Planet distance displayed as raw pixel distance / preset.distanceScale (AU-like units)
  - Trail fade uses destination-out compositing with globalAlpha = 1 - trailFade (0.015)
  - Uses panic logging library (/_lib/panic_v3.js) for info/warning/notice messages
  - Two presets share the same sunMass (3330) but different distanceScale (315 vs 12) for appropriate visualization scale
  - Orbital velocity computed as v = sqrt(G*M/r) where G=1, ensuring circular orbits

Page entièrement générée et maintenue par IA, sans intervention humaine.