Skip to content

feat(layout): concentric ring layouts — hollow centres, symmetric discs, per-project shorthand - #91

Merged
pyramation merged 1 commit into
mainfrom
feat/rings-annulus-layouts
Aug 9, 2026
Merged

feat(layout): concentric ring layouts — hollow centres, symmetric discs, per-project shorthand#91
pyramation merged 1 commit into
mainfrom
feat/rings-annulus-layouts

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

Round rigs stop being "a grid with a circular mask" and become concentric rings, so a 25-light rig can be mapped as a hollow ring, a symmetric disc, or an explicit ring list — per project, as configuration.

New generator, plus an annulus shorthand that picks the rings for you:

ringsLayout({ rings: [{ count: 16, radius: 1 }, { count: 8, radius: 0.6, phase: 22.5 }] })
annulusLayout({ count: 25, innerRadius: 0.5 })  // → 11 + 8 + 6, hole in the middle
annulusLayout({ count: 25, innerRadius: 0 })    // → 12 + 8 + 4 + 1, symmetric disc

annulus derives the ring count from the area per fixture (spacing = sqrt(area/count)), spaces rings evenly across the band, then splits count proportional to each circumference — so along-ring spacing ≈ ring-to-ring spacing, and every ring is exactly even (no distance-tie lopsidedness like filledRing's 3/4/6/6/4/2). Alternate rings are staggered by half a step so fixtures interleave instead of lining up radially. Fixtures are emitted outermost ring first, clockwise from 12 o'clock, so shard slices and light maps stay contiguous per ring; ring indexes from the inside out (0 = centre), perimeter is the outer ring, and there are no grid coords (cols/rows = 0).

filledRing is untouched — the grid-masked disc is still there for rigs that really are a grid.

Config surface, one string anywhere a layout is chosen (parseLayoutSpec):

grid-7x7 | grid:9x4 | ring:6 | filled:25 | annulus:25@0.5 | rings:12,8,4,1

rings:12,8,4,1 spaces radii evenly and treats a trailing 1 as the centre fixture. Wired into wavegrid projects config set layout, wavegrid init, and the desktop create-project wizard + config editor (new "Ring w/ hole" and "Concentric rings" shapes). New presets: ring-25-hollow, disc-25.

Two fixes fell out of it:

  • resolveLayout now prefers an explicit kind over preset — the default config carries layout.preset = 'grid-7x7', which was merged under a project's custom shape and silently won, so every kind-based spec (including the pre-existing grid:/ring: ones from the desktop editor) resolved as a 7×7 grid.
  • Auto-map gained two polar strategies, since round rigs previously only got identity/reverse: ringCounterClockwise (each ring wired the other way from 12 o'clock) and ringsInnerFirst (wiring starts at the centre).

Verified end-to-end through the store: projects config set layout annulus:25@0.525-cannon annulus (rings, 25 cannons), rings:16,925-cannon rings (16+9). No server, receiver, socket or OSC protocol changes — the layout is resolved once and broadcast as before.

Link to Devin session: https://app.devin.ai/sessions/972698f89f494b86828010666a002b8f
Requested by: @pyramation

@pyramation pyramation self-assigned this Aug 9, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pyramation
pyramation merged commit 936a5e5 into main Aug 9, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant