This week the trees are finally sprouting leaves and flowers in Rochester. I started learning about L-systems this week. Coincidence? Pre-planned? Coincidence. But appropriate.
These things, right here!
L-systems are recursion. Visual code, just like our very first Python project in Computer Science 1 class. They’re a rewriting system, consisting of an alphabet/vocabulary of symbols that make rule strings, and grow with each generation according to those rules. They can be very rigid and architectural, or organic and random. Very versatile; both design-y and artsy. But based on math, and created by a biologist/botanist. Often used to model organisms.. molecules.. fractals.. plants. Many other things. I got excited.
I’d say this here is a pretty darn good example of generations of a growing plant. Fairly random-lookin, fairly organic. If I can learn that, ‘twould be cool!
Why do I need L-systems all of a sudden? For the focal point of my piece – the bonfire. Branches, twigs. To start, I quickly mocked up some logs and arranged them in a bonfire:
Now I need to make me some branches.
I’ll make this post into a handy reference for myself, for future endeavors involving L-systems. As I said, L-systems are created based on rules. There’s a base, then there are rules defining the iterations.
Example base: X
Example rule: X = ! /(3) T F[+X] ~F[-X] +X : 0.4
Here’s a much more thorough list of commands: http://www.
So let’s do something. There are two methods of creating L-systems: 1) edge rewriting – replacing edges with the recursion, and 2) node rewriting – appending recursion to the last node.
This Koch star, which started as a triangle, is an example of edge rewriting, as the edges get more complex with each generation. Fun fact: adding a Revolve node to the resulting curve is fun. Or, you know, not stopping with the L-system and actually creating something interesting using it as a stepping stone. (Which is how it should be done.)
And this is a simple example of node rewriting, where the structure actually “grows” with each generation. Very simple rule up there – each time you see a full step, replace it with: a full step, a branch turned right, another full step, a branch turned left, and a third full step.
This example introduces variables – symbols outside of L-system vocabulary that are defined by the artist in the rules. These variables are just another “full step,” but you get to make whatever you want of it. Easy, right? Easy..
But then you add the ! for thickness, to get the branch to thin out on top, and the T for some sagging of the side branches, and “ for curvature, and ~ for twisting, and add values in parentheses like (15) to specify the angle/value of turning/manipulation, and get it more and more and more complex and cool!
So I was already happy with my branch at this point: it had quite a lot of variation and twist to it, looked fairly organic overall! And it doesn’t even include any probability rules!
If you add ‘:number‘ to the end of a rule (like this: X = ! // FF [-X] F [+X] F : 0.8), that number becomes the % of the time that rule gets executed. Randomness!
And there are, of course, conditionals – if statements. F: t>number = rule means execute the rule if the generations are greater than the number specified. Very very cool for structures that age.
But that’s not all. The L-system node in Houdini has four inputs up top, labeled by letters of the alphabet. They’re there for copying geometry onto the ends of branches! Hello, fruits, leaves, atoms, or whatever else your heart desires on the ends of those branches. I quickly threw some randomized berries on my tree, just by taking a sphere, mountain-SOPing it, scattering points on the deformed thing, and copying a little-er sphere onto each scattered point. And plugging that into the J input of the L-system:
Neat. I like it!
The possibilities here, oh man. It would probably help me, being a visual person, to draw the shape of the tree/system/object I want, then figure out how to make that pattern, what building blocks go into it – and then translate that “pseudo code” into L-system rules.
But this was enough for me to make the branches for the bonfire. Here’s what I ended up with. It’s not final, but I’m happy with the direction it’s going:
Next up: the fire and the smoke.