Koch
Definition
n: 2
d: 90
axiom: F - F - F - F
p: F -> F - F + F + F F - F - F + F
Colors: cetI1, Method: index
A L-system, short for Lindenmayer-system, is a mathematical formalism to describe the behaviour of plant cells and to model the growth process of plant development.
For a long time, I was aware of the book "The Algorithmic Beauty of Plants" [ABOP], written by Przemyslaw Prusinkiewicz and Aristid Lindenmayer, but never found the time to study it. I was aware that this book is a real classic in computer science. Maybe I heard of it when I was at university. Now, some decades later, I remembered my desire to read the book. I started looking for a print version in good condition. Eventually, I found one. It was expensive but completely worth the money.
lsys is my modest take on writing an L-system interpreter in Haskell. Find it on codeberg.org/bwolf/lsys.
It implements the following input symbols for the axiom and production
rules: F, f, -, +,
[, ] and ε.
It takes as input an L-system definition, which is a simple file format that describes the relevant aspects of the system. It looks like this:
n: 5
d: 90
axiom: L
p: L->+RF-LFL-FR+
p: R->-LF+RFR+FL-
Here, n is the number of iterations, d is the
rotation angle, and axiom is the start configuration, which gets
rewritten in each iteration by the production rules denoted
byp.
This is used to drive turtle graphics (well known from [Logo]),
where the turtle initially looks straight up. When a rotation command
+ or - is read, the turtle is rotated by the angle
delta (d). A draw command is an upper-case letter, which moves
the turtle by some unit, resulting in a line being drawn. A move command works
similarly with lower-case letters.
Stack commands are [ and ]. The former pushes the
turtle state onto the stack, the latter pops the turtle state from the stack.
The ε symbol is supported in production rules to state that a symbol
should be replaced by nothing.
All parameters of a system (like the number of iterations) can be overridden via command line arguments.
For coloring the drawings, a few simple methods are implemented: by index, distance, height and default. Default is the simplest, which only takes the foreground and background color into account. The other methods produce, for a line, an palette index which is used to index a perceptually uniform color map.
n: 2
d: 90
axiom: F - F - F - F
p: F -> F - F + F + F F - F - F + F
Colors: cetI1, Method: index
n: 4
d: 90
axiom: F-F-F-F
p: F->F-FF--F-F
Colors: cetC1, Method: index
n: 4
d: 90
axiom: -F
p: F->F+F-F-F+F
n: 6
d: 60
axiom: R
p: F->R+F+R
p: R->F-R-F
n: 5
d: 25.7
axiom: F
p: F->F[+F]F[-F]F
Colors: cetL10, Method: distance
n: 5
d: 20
axiom: F
p: F->F[+F]F[-F][F]
Colors: cetL19, Method: distance
n:4
d:22.5
axiom:F
p:F->FF-[-F+F+F]+[+F-F-F]
Colors: cetI2, Method: distance
n:7
d:20
axiom:X
p:X->F[+X]F[-X]+X
p:F->FF
Colors: cetCbl2, Method: distance
n:7
d:25.7
axiom:X
p:X->F[+X][-X]FX
p:F->FF
Colors: cetL08, Method: distance
n:5
d:22.5
axiom:X
p:X->F-[[X]+X]+F[+FX]-X
p:F->FF
Colors: cetD10, Method: distance
n: 10
d: 90
axiom: F
p: F->F+R+
p: R->-F-R
Colors: cetL17, Method: index
n: 5
d: 60
axiom: F
p:F->F+R++R-F--FF-R+
p:R->-F+RR++R+F--F-R
Colors: cetL12, Method: index
n: 5
d: 90
axiom: L
p: L->+RF-LFL-FR+
p: R->-LF+RFR+FL-
Colors: cetC1, Method: index
n: 4
d: 36
axiom: [N]++[N]++[N]++[N]++[N]
p: M->OF++PF----NF[-OF----MF]++
p: N->+OF--PF[---MF--NF]+
p: O->-MF++NF[+++OF++PF]-
p: P->--OF++++MF[+PF++++NF]--NF
p: F->ε
Colors: cetL10, Method: height
Copyright © 2026 M. Geiger