Walldye

Four-note rings

inspired by Josef Müller-Brockmann, Beethoven1

Thirteen rings of arcs circle a filled dot, each playing three short notes and a long one, a beat later than the ring inside. One long note is lit.

Made with Claude Opus 5.5

Technique
flat shapes
Inspired by
modernism
Shape
Any screen
Added
27 September 2026

Colours

  • #1C1B1Abackground
  • #DAD8CEforeground
  • #CF6A4Caccent

Export

Format
Shape
Size

Notes

Takes the segmented rings of Josef Müller-Brockmann’s Beethoven poster (1955).

Each ring here is one bar over a three-quarter turn, three short notes and a long one, started a beat later than the ring inside it, so the rests wind outward instead of lining up.

Sources

  1. Josef Müller-Brockmann, Beethoven, 1955. ↑

Source code

wallpapers/beethoven-arcs/design.py, 37 lines

"""Concentric rings cut into beat-long arcs, each ring playing short-short-short-long one beat later than the last, so the rests wind outward."""

from walldye import ACCENT, ACCENT_1, BG_ALT, UI_ALT, Canvas, P, design, ramp

LO, BEAT, BEATS = 200, 22.5, 12  # twelve beats make a three-quarter turn
R0, GROWTH = 48, 1.18  # ring k has radius R0 * GROWTH**k and a stroke a tenth of that
RINGS = 13
# One bar, "#" sounds and "." rests: three short notes, then a long one. Ring k starts it k
# beats late, so each ring's rests sit one beat further round than the ring inside it.
MOTIF = "#.#.#.#####."
LIT = 7  # the ring whose long note is lit
LEAD = ACCENT_1  # the innermost ring
TONES = ramp(UI_ALT, BG_ALT, RINGS + 1)  # the rest, quieter towards the outside


@design(aspects="any")
def draw(s: Canvas) -> None:
    # landscape: right of centre; portrait: centred, low
    c = s.pick(landscape=(0.7, 0.6), portrait=(0.6, 0.56))
    s.fill(P().circle(c, 22), ACCENT)
    for k in range(1, RINGS + 1):
        r = R0 * GROWTH**k
        bar = MOTIF[-(k - 1) % len(MOTIF) :] + MOTIF[: -(k - 1) % len(MOTIF)]
        ring, lit = P(), P()
        b = 0
        while b < BEATS:
            if bar[b] == ".":
                b += 1
                continue
            e = b
            while e < BEATS and bar[e] == "#":
                e += 1
            span = (LO + b * BEAT, LO + e * BEAT)
            (lit if k == LIT and e - b > 1 else ring).arc(c, r, deg=span)
            b = e
        s.stroke(ring, LEAD if k == 1 else TONES[k], r * 0.1)
        s.stroke(lit, ACCENT, r * 0.1)

Run it yourself

$ git clone https://github.com/nickolaj-jepsen/walldye && cd walldye$ uv run walldye render beethoven-arcs --theme fireproof -o beethoven-arcs-fireproof-16x9.svg