4.0 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
A 3D orbital mechanics simulation using a 2-body gravitational model with sphere of influence (SOI) transitions. The simulation features real-time visualization using raylib and supports configurable star systems via text files.
Architecture
Code Style
This project uses C-style C++: structs and functions, no classes or templates. All headers use include guards. Memory management uses malloc/free.
Core Components
Physics Layer (physics.h/cpp)
- Vector math operations (Vec3 struct with add, sub, scale, normalize, magnitude, distance)
- Gravitational force calculation using Newton's law: F = G * m1 * m2 / r^2
- Euler integration for position/velocity updates
- Defines gravitational constant G = 6.67430e-11
Simulation Layer (bodies.h/cpp)
CelestialBodystruct: stores name, mass, radius, position, velocity, SOI radius, parent index, colorSimulationStatestruct: manages array of bodies, body count, simulation time, time step (dt)- SOI (sphere of influence) calculations using Hill sphere approximation
- Dynamic parent switching when bodies cross SOI boundaries
find_dominant_body()determines which body has gravitational dominanceupdate_simulation()runs one physics step: finds dominant parent, calculates gravity, applies Euler integration
Configuration Layer (config_loader.h/cpp)
- Parses text configuration files with format:
name mass radius x y z parent_index r g b - Automatically calculates circular orbit velocities for all bodies
- Calculates SOI radii for all bodies based on parent relationships
- Comments start with
#, parent_index -1 indicates root bodies (stars)
Rendering Layer (renderer.h/cpp)
RenderStatestruct: manages Camera3D, distance_scale, size_scale, show_info flag- Uses logarithmic distance scaling for visualization (astronomical distances → screen coordinates)
- Uses exponential size scaling for body rendering (realistic radii → visible spheres)
- Implements 3D camera controls via arrow keys
- Renders bodies as colored spheres using raylib
Main Program (main.cpp)
- Initializes simulation with MAX_BODIES=100, TIME_STEP=60 seconds
- Runs 100 physics steps per frame for stability (adjustable with speed multiplier)
- Game loop: input handling → camera update → physics update (if not paused) → rendering
- Supports speed multiplier (2x/0.5x per keypress, min 0.125x)
Data Flow
- Configuration file →
load_system_config()→ populatesSimulationState calculate_initial_velocities()→ sets circular orbit velocitiescalculate_soi_radii()→ computes sphere of influence for each body- Main loop:
update_simulation()→ for each body:find_dominant_body()→ determine gravitational parentcalculate_gravity_force()→ compute force from parenteuler_step()→ update position/velocity
render_simulation()→ for each body:scale_position()→ convert to render coordinatesscale_radius()→ convert to render sizerender_body()→ draw sphere with color
Key Implementation Details
SOI Transitions: Bodies dynamically switch gravitational parents when crossing sphere of influence boundaries. The switch uses a 0.5x distance hysteresis to prevent oscillation.
Rendering Scales: Astronomical scales are incompatible with graphics. The renderer applies:
- Logarithmic distance scaling to fit solar system in viewport
- Exponential size scaling to make small bodies visible
- Both scales are configurable in
RenderState
Physics Stability: Multiple physics steps per frame (100x by default) provide smoother integration. The time step is 60 seconds, so each frame simulates 6000 seconds of time at 1x speed.
Velocity Calculation: Initial velocities for circular orbits are calculated using v = sqrt(G * M / r) where M is parent mass and r is orbital radius.