exupero's blog
RSSApps

More Lindenmeyer fractals

In the previous post, I used a straight-forward data format to define Lindenmeyer systems. Here I'll draw a few more L-system fractals, starting with the space-filling Hilbert curve:

(def hilbert-curve
  '{:axiom [A]
    :rules {A [+ B F - A F A - F B +]
            B [- A F + B F B + F A -]}
    :moves {+ [:turn 90]
            - [:turn -90]
            F [:forward 1]}})

which at the fifth level of recursion looks like this:

hilbert-curve.png

Here's the Koch curve, two levels deep:

(def koch-curve
  '{:axiom [F + F + F + F]
    :rules {F [F + F - F - F F + F + F - F]}
    :moves {+ [:turn 90]
            - [:turn -90]
            F [:forward 1]}})
koch-curve.png

A SierpiƄski triangle, at seven levels:

(def sierpinski-triangle
  '{:axiom [A F]
    :rules {A [B F - A F - B]
            B [A F + B F + A]}
    :moves {+ [:turn -60]
            - [:turn 60]
            F [:forward 1]}})
sierpinski-triangle.png

And the dragon curve, at 11 levels:

(def dragon-curve
  '{:axiom [F X]
    :rules {X [X + Y F +]
            Y [- F X - Y]}
    :moves {+ [:turn -90]
            - [:turn 90]
            F [:forward 1]}})
dragon-curve.png

You can find more fractal-generating L-systems in this Observable, including Penrose tiles and asymmetrical plant-like forms, which rely on nesting contexts that aren't supported by the scheme here. One of my favorites from Kelley's post is the hexagonal gosper:

(def hexagonal-gosper
  '{:axiom [X F]
    :rules {X [X + Y F + + Y F - F X - - F X F X - Y F +]
            Y [- F X + Y F Y F + + Y F + F X - - F X - Y]}
    :moves {+ [:turn -60]
            - [:turn 60]
            F [:forward 1]}})
hexagonal-gosper.png

I haven't given much thought to how I'd support nesting contexts with this data-driven approach. For the moment I'd like to explore in a different direction.