Type a string of A and B and the logistic map grows gold and teal enamel jewelry.
Markus-Lyapunov fractals force the logistic map x' = rx(1 - x) with a repeating sequence of letters: A means use r = a, B means use r = b, and every pixel is one pair (a, b). After a warmup the program averages log |r(1 - 2x)| (multiplying derivatives and taking a log only every eighth step) to get the Lyapunov exponent: negative where the forced orbit settles into a rhythm, positive where it is chaotic. That exponent becomes a height field lit by a slowly circling lamp: stable regions are polished gold domes rising toward the superstable curves, chaotic regions are recessed teal enamel with a glassy highlight, and the zero contour between them is a raised gold wire, like cloisonne. The plane is sampled every 8 pixels, then 4, 2 and 1, each level shown smoothly upscaled when complete, and during zooms and pans the last sharp image is reprojected so motion stays fluid. The inset cobwebs the forced orbit at the cursor, each step drawn in the color of the parabola it used.
Try it. Type A and B to extend the sequence (Backspace deletes a letter, Esc starts a new one) and watch the landscape regrow. Scroll or double-click to zoom (Shift double-click zooms out), drag to pan, and hover anywhere for its cobweb and exponent. Enter jumps to the next preset, 0 resets the view; left alone, it tours famous sequences such as Zircon Zity.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a Markus-Lyapunov fractal renderer with JavaScript and the HTML canvas element. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
The idea: take the logistic map x = r * x * (1 - x), but switch r every step according to a repeating sequence of letters such as "AABAB", where A means r = a and B means r = b. Each pixel is one pair (a, b), with a running from 2 to 4 across the canvas and b from 2 to 4 up it.
Start simple:
- Make a canvas that fills the window. Render into a smaller offscreen canvas (about half the size) with ImageData and draw it scaled up.
- For each pixel, start at x = 0.5, iterate 50 times to warm up, then iterate 200 more while summing log(abs(r * (1 - 2x))). The average is the Lyapunov exponent.
- Color negative exponents (stable) in gold, brighter the more negative, and positive ones (chaotic) in deep teal.
- Compute a band of rows per animation frame so the page never freezes, and add a text box where I can type a new sequence of A and B.
Once that works, make it beautiful:
- Render progressively: first every 8th pixel, then every 4th, 2nd and 1st, showing each level smoothly scaled as soon as it is done.
- Treat the exponent as a height map. Compute a normal from neighboring heights and light it with a moving light (diffuse plus a tight specular highlight), so the gold looks like polished metal and the teal like glassy enamel. Make the zero contour a thin raised gold line.
- Add mouse wheel zoom around the cursor.
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 famous sequences like BBBBBBAAAAAA (Zircon Zity), a cobweb inset of the forced orbit under the cursor, or reprojecting the old image while a zoom is computing.