One grating, one true motion, three holes that each report a different direction.
Diagonal stripes move behind a card cut with a circle, a tall slot and a wide slot, and each hole shows them moving a different way; an idle tour also visits a barber pole, rendered per pixel as a lit cylinder whose helical stripes bend toward its edges, and two plaids. Through a hole an edge only reveals the part of its velocity perpendicular to itself, so every velocity on one constraint line looks identical. The arrows come from a terminator model evaluated on the real outline: line ends slide along the rim, and averaging their velocities over the rim gives the normal velocity for a circle and the long axis for a slot, the barber pole effect. The velocity space panel draws the constraint line, the true velocity and each hole's percept, and plaids show two ambiguous gratings combining at the intersection of their constraints, even for type II plaids where the vector average points elsewhere.
Try it. Drag the handles to reshape any hole (the outline is a closed B-spline), drag inside a hole to move it, and drag the open card to turn the stripes. Drag the white ring in velocity space to change the true motion. Switch between apertures, a barber pole and two plaids (1 to 4), press T to add texture that reveals the true motion, and use the arrows for angle and speed. Any touch or key stops the idle tour.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build an aperture problem demo with JavaScript and the HTML canvas element: the same moving diagonal stripes seen through a circle, a tall slot and a wide slot, each seeming to move a different way. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Make a canvas that fills the window, stays sharp on high-DPI screens (scale by devicePixelRatio), and resizes with the window. Paint it near black.
- Draw a grating: rotate the context to 45 degrees and fill alternating light and dark bars. Each frame, shift the bars along their normal by speed times time, so they move.
- Build one path containing a circle, a tall rounded rectangle and a wide rounded rectangle, clip to it, and draw the grating inside, so the stripes are only visible through the three holes.
- Outline each hole in its own color.
Once that works, make it beautiful:
- Compute what each hole should look like it does with a terminator model: walk around the outline in small segments with unit tangent t; with stripe normal n and normal speed s, add sign(t . n) * t * length to a sum and abs(t . n) * length to a weight. The perceived velocity is s * sum / weight. Draw it as an arrow from each hole's center.
- Add a small velocity space diagram: the dashed constraint line of every velocity with the same normal component, and each hole's arrow ending on it.
- Let me drag the holes around and drag their corners to reshape them, and watch the arrows update.
Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as a barber pole with stripes on a shaded cylinder, a plaid made of two gratings that moves where their constraint lines cross, or sprinkling dots on the stripes to reveal the true motion.