Skip to content

Instantly share code, notes, and snippets.

@lynaghk
Created November 9, 2025 10:57
Show Gist options
  • Select an option

  • Save lynaghk/e3761bcdc65cb47823faa11d96c1ad67 to your computer and use it in GitHub Desktop.

Select an option

Save lynaghk/e3761bcdc65cb47823faa11d96c1ad67 to your computer and use it in GitHub Desktop.
# transcript of claude explaining https://github.com/Will-Morr/MarbleFountain/tree/9baa9822d03ec81b9fe26bbd0397b69164c9d44e
╭─── Claude Code v2.0.31 ────────────────────────────────────────────────────────────────────────────────────╮
│ │ Tips for getting started │
│ Welcome back Kevin! │ Run /init to create a CLAUDE.md file with instructions for Claude │
│ │ ───────────────────────────────────────────────────────────────── │
│ ▐▛███▜▌ │ Recent activity │
│ ▝▜█████▛▘ │ No recent activity │
│ ▘▘ ▝▝ │ │
│ │ │
│ Sonnet 4.5 · API Usage Billing │ │
│ /Users/dev/software/MarbleFountain │ │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
> I think there's a particle simulation somewhere in here that generates the support structures. Can you please find where in the code this is and explain how it works?
⏺ I'll search through the codebase to find the particle simulation that generates support structures.
⏺ Explore(Find particle simulation code)
⎿  Done (18 tool uses · 61.9k tokens · 45.9s)
⏺ I found the particle simulation! It's located primarily in openScadGenerators.py starting around line 771. Here's how it works:
Overview
The system uses a physics-based particle simulation where each support column is represented as a particle that moves through space layer-by-layer, avoiding the marble track while trying to connect structures
together.
Core Components
1. Particle Class (column) - Line 771
Each particle tracks:
- Position & velocity: Current/previous XY position, velocity vector
- Size: Influences attraction strength and final support radius
- History: Position history used to build the final 3D support geometry
- Merge tracking: Records when columns merge together
2. Force System
The simulation applies competing forces each frame:
Repulsion from Track (calculateRepulsivesSupportForces - Line 784):
- Pushes particles away from the marble track paths
- Only applies when Z-height difference is within 3-6× marble radius
- Force strength: PEAK_REPULSION_MAG * pow(xyDistance, 2) * pow(zDistance, 2)
- This prevents supports from colliding with the track!
Attraction Between Particles (calculateAttractiveSupportForces - Line 816):
- Pulls nearby particles together (inverse square law: 80.0 / distance²)
- Helps consolidate multiple thin supports into fewer thick ones
- Max attraction distance: ~20mm
Boundary Forces (calculateBoundarySupportForces - Line 843):
- Keeps particles inside the build volume bounding box
Centering Force (calculateCenteringForce - Line 853):
- Gently pulls particles toward a target radius from center
- Helps organize support layout
3. Main Simulation Loop (calculateSupports - Line 881)
The algorithm works top-to-bottom through the model in 0.5mm layers:
For each Z-layer (from top to bottom):
1. Update all active particle positions with forces
2. Apply drag: velocity *= 0.8
3. Update position: currPos += velocity
4. Merge particles within 0.5mm of each other
5. Spawn new particles at anchor points (where track needs support)
Key physics parameters:
- PARTICLE_DRAG = 0.8 (simulates friction)
- MAX_PARTICLE_VEL = 1.0mm per layer
- MERGE_RAD = 0.5mm (particles this close merge together)
4. Priority System
The simulation uses a clever priority ratio that determines which forces dominate:
- High priority: Boundary forces and track repulsion (collision avoidance)
- Low priority: Attraction and centering forces
- This ensures supports never hit the track even when being pulled together
5. Geometry Generation (generateSupports - Line 1089)
After simulation completes:
1. Each particle's position history becomes a path through 3D space
2. Creates chain-hulled spheres along each path
3. Radius varies based on particle size (maps to 1.5-3.0mm range)
4. Smoothly transitions radius during merges
5. Connects bottoms to base plate
Why This Approach?
This physics-based method elegantly solves the support generation problem:
- ✅ Automatic collision avoidance via repulsion forces
- ✅ Natural branching as supports merge while descending
- ✅ Structurally sound paths with smooth curvature
- ✅ Configurable via force constants in defs.py
The key files are:
- openScadGenerators.py:771-1400 - Main simulation
- defs.py - Physics constants
- shared.py - Utility physics functions
> /cost
⎿  Total cost: $0.0370
Total duration (API): 1m 21s
Total duration (wall): 1m 36s
Total code changes: 0 lines added, 0 lines removed
Usage by model:
claude-haiku: 0 input, 3.6k output, 0 cache read, 0 cache write ($0.0179)
claude-sonnet: 0 input, 1.3k output, 0 cache read, 0 cache write ($0.0191)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment