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

View file

@ -0,0 +1,29 @@
{
"permissions": {
"allow": [
"Bash(pkg-config --list-all)",
"Read(//usr/include/GLFW/**)",
"Bash(ldconfig -p)",
"Bash(make *)",
"Bash(echo \"exit: $?\")",
"Bash(timeout 2 ./vectorgons)",
"Read(//tmp/**)",
"Bash(glxinfo)",
"Bash(grep -iE '^\\(scrot|grim|import|maim|spectacle\\)$')",
"Bash(convert vg_shot.png -crop 270x210+0+0 +repage -resize 300% vg_crop.png)",
"Bash(identify -format \"%wx%h\\\\n\" vg_multi.png)",
"Bash(convert vg_multi.png -crop 760x600+460+0 +repage vg_multi_solids.png)",
"Bash(convert vg2.png -crop 740x620+0+0 +repage vg2_crop.png)",
"Bash(convert vg_ast.png -resize 1000x vg_ast_full.png)",
"Bash(xwininfo -name Vectorgons -int)",
"Bash(timeout 3 ./vectorgons)",
"Bash(timeout 4 ./vectorgons)",
"Bash(cat)",
"Bash(cc -O2 -o /tmp/sim /tmp/sim.c -lm)",
"Bash(/tmp/sim)",
"Bash(cc -O2 -o /tmp/st2 /tmp/st2.c -lm)",
"Bash(/tmp/st2)",
"Bash(rm -f /tmp/st2 /tmp/st2.c)"
]
}
}

19
Makefile Normal file
View file

@ -0,0 +1,19 @@
CC ?= gcc
CFLAGS ?= -O2 -Wall -Wextra -std=c11
PKGS = glfw3 glu
CPPFLAGS += $(shell pkg-config --cflags $(PKGS))
LDLIBS += $(shell pkg-config --libs $(PKGS)) -lGL -lm
TARGET = vectorgons
SRC = vectorgons.c
$(TARGET): $(SRC)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(SRC) $(LDLIBS)
run: $(TARGET)
./$(TARGET)
clean:
rm -f $(TARGET)
.PHONY: run clean

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

BIN
vectorgons Executable file

Binary file not shown.

1607
vectorgons.c Normal file

File diff suppressed because it is too large Load diff