L-systems : draw nice fractals and plants (part I)

Hassen Harzallah
6 min readFeb 9, 2020

--

Note: part II is available here.

In 1968, Hungarian botanist Aristid Lindenmayer developed a grammar-based system to model the growth patterns of plants. Lindenmayer systems — or L-systems for short — were originally conceived as a mathematical theory of plant development. However, we are going to use them generate self-similar fractal patterns.

Fractals are mathematical object whose structure stays the same after changing the scale. As described by Benoit Mandelbrot, it is “a rough or fragmented geometric shape that can be split into parts, each of which is (at least approximately) a reduced-size copy of the whole.”

Fractal example : each part is a reduced-size copy of the whole

On one side, a central concept of L-systems is that of rewriting. It is a technique for defining complex objects by successively replacing parts of a simple initial object using a set of rewriting rules.

On the other side, a fundamental component of fractals geometry is recursion, which is the repeated application of a rule to successive results. Therefore, the rewriting concept of L-systems is an efficient mechanism to apply recursion in order to achieve complex fractals.

For now, let’s take the L-system in their most basic form: a method to generate a sentence using rules. We will see later how to explore this to generate shapes instead of words and sentences.

L-systems involves three main components:

1. Alphabet: a set of valid characters that can be included in a “sentence”. For example, if the alphabet is “ABC”, any valid “sentence” will contain the three characters : A, B and C.

2. Axiom: The sentence that describes the initial state of the system. For example, using the alphabet “ABC,” some example axioms are “AAA” or “B” or “ACBAB.”

3. Rules: they are applied to the axiom and then applied recursively, generating new sentences over and over again. An L-system rule includes two sentences, a “predecessor” and a “successor.” For example, with the Rule “A → AB”, whenever an “A” is found in a string, it is replaced with “AB.”

Let’s begin with a very simple L-system. (This is, in fact, Lindenmayer’s original L-system for modeling the growth of algae.)

Alphabet : A B

Axiom : A

Rules : ( A -> AB) ( B -> A )

The first generations of the previous L-system (source: The Nature of Code)

We take the axiom sentence and apply the rule to it to get a new sentence : that is the first generation. We reapply the rules to each generation and each time we get a new sentence.

Now, you may be asking what all of this has to do with fractal generation? The answer of this question is that we can replace each letter of the alphabet with an action. For example, A can be used to draw a line and B can be used to move without drawing.

Example 1: Cantor set

Let’s take our first example with shapes.

Alphabet: A B

Axiom: A

Rules: ( A -> ABA ) ( B -> BBB )

A: Draw a line forward.

B: Move forward without drawing.

Let’s look at the output of a few generations:

Generation 0: A

Generation 1: ABA

Generation 2: ABABBBABA

Generation 3: ABABBBABABBBBBBBBBABABBBA

Now, let’s replace each letter of the alphabet with its corresponding action. We get the Cantor set, which is one of the first fractals discovered in modern mathematics. It was developed in 1883 by the German mathematician George Cantor.

Cantor set generated by an L-system

After this basic example, let’s tackle to more interesting examples. For the next examples, we will use the following alphabet which is often used with L-systems : “FG+-[]”, with :

F: Draw a line and move forward

G: Move forward (without drawing a line)

+: Turn right

-: Turn left

[: Save current location

]: Restore previous location

This type of drawing framework is called “Turtle graphics”, it is like having a turtle in the screen and being able to command it to move in different directions. We need to adjust some parameters before using this alphabet such as the length of the line that should be drawn, the angle of rotation while turning, and we can also add a scale factor to scale down the length of lines in each generation.

Example 2: Snowflake curve

The snowflake curve is a famous fractal, proposed by Von Koch in 1905.

To generate the snowflake curve we are going to use two shapes : an initiator and a generator. The generator is applied to each line of the initiator, then we get the first generation. We apply this rule again to get the next generations and each time we scale down the generator in order to have the same length as the lines.

Initiator and generator (source : The Algorithmic Beauty of Plants)

As we are going to use an L-system to generate this snowflake curve. Our axiom is going to be the sentence representing the initiator. Then, we have to figure out the rule that transforms a line to the generator shape.

Let’s begin by translating the generator to a rule. We need to write a sentence capable of transforming a line to the shape corresponding to the generator.

The generator takes a vertical line and add a small triangle shape in its middle.

It is the following rule : ( F -> F-F++F-F ). With an angle of rotation of 60 degrees, which correspond to the angle of an equilateral triangle. A scaling factor of 1/3 has been added to each generation to ensure that the length of the shape remains the same in each generation.

For the initiator, we will use the following axiom : F++F++F which correspond to drawing a vertical line, then making a 120 degrees rotation and drawing a line, then rotating 120 degrees again and drawing the final line to complete the triangle.

Initiator and the first generations of snowflake curve using L-system.

Alphabet : F G + — [ ]

Axiom : F++F++F

Rule : ( F -> F-F++F-F )

Now as we generated the snowflake curve with an L-system, we have seen how it is possible to reproduce shapes from nature with a recursive system. Let’s try to go further by reproducing a plant shape with an L-system.

Other Examples:

Koch Curve:

Alphabet : F G + — [ ]

Axiom : + F

Rule : ( F -> F+F−F−F+F)

Koch Curve (source : Wikipedia)

Sierpinski triangle:

Alphabet : F G + — [ ]

Axiom : F

Rule : ( G -> F-G-F) ( F -> G+F+G)

Sierpinski triangle (source: Wikipedia)

Try it yourself !

If you want to experiment yourself with L-systems, you can use my Python code to draw your own fractals. Check this at my Github project : https://github.com/hhassen/L-system

Feel free to share your fractals, to improve the code or to share your suggestions.

Conclusion

L-system is a powerful system that can allow us to generate fractals, as well as plants (as we are going to see in the next article).

L-systems are used today not only to generate 2d fractals and plants, but also to generate 3d shapes and even generate a whole world in video games. For instance, “No Man’s Sky” developers took the approach of L-systems and extended its use to generate a procedural game world which feels deep and coherent.

References :

“The Nature of Code” by Daniel Shiffman

“The Algorithmic Beauty of Plants” by Przemyslaw Prusinkiewicz & Aristid Lindenmayer

--

--