Excellent state.

This commit is contained in:
The Dust Council 2026-06-01 21:59:36 -07:00
commit d85fb2e638
5 changed files with 1796 additions and 0 deletions

141
README.md Normal file
View file

@ -0,0 +1,141 @@
# Vectorgons
A starfield simulator — except instead of stars, colorful **vector-drawn
platonic solids** tumble through space toward the camera.
**~110 shape types** are rendered as glowing wireframes — each spawns far away
at a random size, tumbles on its own random axis, and streams past the camera
before being recycled at the render-distance sphere. Solids never overlap.
The shape set includes:
- **Platonic solids:** tetrahedron, cube, octahedron, dodecahedron, icosahedron
- **Other polyhedra:** cuboctahedron, truncated octahedron, stella octangula
- **Prisms / antiprisms / bipyramids** (various base polygons)
- **Many-faced solids named for their face count:** tridecahedron (13),
tetradecahedron (14), pentadecahedron (15), heptadecahedron (17),
octadecahedron (18), enneadecahedron (19), icosahedron (20),
icositetrahedron (24), triacontahedron (30), hexacontahedron (60), and
hecatohedron (100) — built from prism / bipyramid / trapezohedron families so
each lands on exactly the requested number of faces
- **Star polygons:** {5/2}, {6/2}, {7/2}, {7/3}, {8/3}, {9/2}, {9/4}, {12/5},
plus the **unicursal hexagram**
- **Googie / atomic-age shapes**, most in both flat **2-D** and **3-D** forms:
jet-age bowling-alley twinkles (4- and 8-point), a layered double starburst,
an atomic burst with electron caps, a ray sunburst, boomerangs, kidney/amoeba
blobs, orbital atoms, concentric orbit rings, and a dense ray-star — plus the
naturally-3-D **Sputnik** satellite, a three-ring **gyroscope** cage, and a
spike-orb sea-urchin
- **Symbols & signs**, each in a flat **2-D** and an extruded **3-D** form:
smiley face, biohazard, peace sign, cross, question mark, exclamation point,
hash/pound (`#`), dollar sign (`$`), and pound sterling (`£`)
- **Random 3-D asteroids:** lumpy convex-hull rocks generated fresh each run,
with random vertex counts (≈726) giving each a different number of sides and
level of complexity
- **4-, 5- and 6-dimensional polytopes:** the 5-cell, **tesseract (hypercube)**,
penteract (5-cube), 6-cube, 16-cell, 5- and 6-orthoplexes, the 24-cell, and
the 5-simplex. These are rotated *in their own dimension* and
perspective-projected down to 3D every frame, so they morph (the classic
"cube-within-a-cube" unfolding) while also tumbling in 3D.
## Build & run
Requires a C compiler, GLFW3, and GLU (all detected via `pkg-config`).
```sh
make
./vectorgons # or: make run
```
## Settings persistence
Your settings are saved automatically on exit to `~/.vectorgons` (a plain
`key=value` text file) and reloaded on the next launch as the new defaults — so
the speed, tumble, render distance, density, colors, glow, fullscreen, etc. you
last used carry over. Delete the file to return to the built-in defaults; it's
safe to hand-edit (values are range-clamped on load).
## On-screen display
A vector-drawn OSD (top-left) lists every setting and its key binding. It
stays fully visible for **10 seconds** after your last keypress, then fades
out over a few seconds. Press any key to bring it back.
## Controls
| Setting | Keys | Notes |
|---------------------|-----------------|------------------------------------------|
| Move camera | `W`/`A`/`S`/`D` | Pan the camera up / left / down / right (hold to fly) |
| Rotate camera | `←`/`→`/`↑`/`↓` | Yaw / pitch the camera view (hold to turn) |
| Approach speed | `PgUp`/`PgDn` | How fast solids fly at you; `PgDn` past 0 reverses (fly backward) |
| Tumble rate | `Q` / `E` | Base rotation speed |
| Tumble variance | `T` / `Y` | Spread of tumble speeds: low = uniform, high = a very wide range (responds live) |
| Render distance | `Z` / `X` | Radius of the field sphere / far plane (401520; hold to ramp) |
| Density | `+` / `-` | Baseline number of solids (scales up with render distance; readout shows the live count) |
| Size min | `U` / `J` | Minimum random solid size |
| Size max | `I` / `K` | Maximum random solid size |
| Hue | `[` / `]` | Base color |
| Hue cycle | `C` / `V` | Continuously cycle through all hues (0 = off); all objects sweep the spectrum |
| Color mode | `M` | Toggle **single-hue****multicolor** |
| Glow | `O` / `L` | CRT glow / light bleed around vectors |
| Flicker | `G` / `H` | Vector flicker intensity |
| Shapes | `N` | Toggle random ⇄ cycling shape spawns |
| Fullscreen | `F` or `F11` | Toggle fullscreen |
| Pause | `Space` | |
| Quit | `Esc` | |
## Color modes
- **Single hue:** every solid uses the hue set with `[` / `]`.
- **Multicolor:** each solid gets its own hue (its base offset plus the
global hue, so `[` / `]` rotates the whole palette).
- **Hue cycle (`C` / `V`):** continuously advances the base hue over time (up
to ~120°/sec). In single-hue mode every object sweeps through the spectrum
together; in multicolor mode the whole palette rotates. Set to `0` to stop.
## How it works
- **Geometry** comes from an N-dimensional polytope engine (36 dimensions).
For regular figures, edges are derived automatically by connecting every
vertex pair at the shared minimum distance; parametric families (prisms,
stars, ...) set edges explicitly.
- **Higher-dimensional shapes** keep their full 4/5/6-D coordinates and are
rotated in their own dimension (driven by the tumble angle plus a per-body
phase), then perspective-projected down to 3D each frame and renormalized to
the unit sphere — which also keeps the no-overlap bound intact.
- **Asteroids** scatter random points over a sphere at jittered radii and wire
them up as a brute-force convex hull, so each rock is a unique faceted blob.
- **The field is a sphere** of radius *render distance* centered on the camera.
Bodies stream along Z (or +Z when speed is negative) and, once they leave the
sphere, are recycled back to the **render-distance shell** on the incoming
side — so objects always appear far away and approach, never popping in close.
They ease in over a fraction of a second at the shell. The initial fill spreads
bodies through the volume so the field starts populated. Because culling is
purely radial, the camera can yaw/pitch a full 360° without revealing an edge.
- **Render distance** (`Z`/`X`, 401520) sets the sphere radius and the
perspective far plane. The **active body count scales with it**, so a deeper
field simply holds proportionally more shapes (constant near-field density)
instead of thinning out to empty space — the `DENSITY` readout shows the live
count, and `+`/`-` sets the baseline (the count at the default distance).
- **The camera** pans in world space via `WASD` and yaws/pitches via the arrow
keys (both polled per frame so movement is smooth and frame-rate
independent); the rest of the field streams past it.
- **No overlap:** each solid's bounding-sphere radius equals its size, and
spawn positions are rejection-sampled so no two spheres intersect (with a
margin). Because every solid translates by the same amount each frame,
non-overlap at spawn is preserved for the body's whole flight.
- **Tumble variance** is applied live as a log-uniform spread
(`spin = 4^(seed · variance)`), so changing it re-spreads every solid's
rotation rate instantly — `0` makes them all tumble alike, `100` gives a
very wide range.
- **CRT glow** wraps each sharp vector in a soft phosphor mist: many faint
additive width layers fade outward into a halo, and a few faint enlarged
ghost copies bloom that glow into a larger volume than the hardware line-width
cap (~10px) could reach on its own. The crisp core is drawn last so the vector
stays sharp; the glow setting scales the mist's spread and brightness.
- **Flicker** randomly dips each solid's brightness per frame, scaled by the
flicker setting.
- **Rendering** uses legacy OpenGL immediate mode (`GL_LINES`) with additive
blending, MSAA, and line smoothing; depth-based fading brightens and
thickens solids as they approach. The OSD uses a self-contained vector
stroke font (no font dependencies).