vectorgons/README.md
2026-06-01 21:59:36 -07:00

141 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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).