[1]The class of grammar-based fractals known as Lindenmayer system [2] allows generating an interesting variety of geometrical and botanical visuals.
To the right is a representation of a “Fractal Plant”, which is generated from just two simple (if cryptic-looking) rules applied recursively.
In simple terms, L-System starts from a string (called an axiom), to which rules are applied recursively. Rules are a set of substitution strings for characters in the original string.
Classic Algae
For illustration,the classic example (named “Algae”), has two rules:
A -> AB (each A becomes AB) B -> A (each B becomes A)
And when you start from “A” as axiom, that gives the following recursive sequence:
n = 0 : A n = 1 : AB n = 2 : ABA n = 3 : ABAAB n = 4 : ABAABABA
Obtaining graphics
When you couple the above system with Turtle graphics [3], these strings can be used as the basis of a vector drawing. Combine a well chosen grammar with a bit of coloring, and you can obtain visually pleasing fractals.
[4]Lindenmayer [5] started from a botanical perspective, but the grammar system can be applied to a variety of mathematical entities, like the Peano-Gosper curve you can see to the left.
A variety of tilings and Kolams [6] can also be achieved.
Coloring can be handled via turtle language commands directly, but also by coloring the lines from start to finish, such as in the Peano-Gosper curve here, where the colors are taken form a rainbow 1D texture.
Finally, L-System fractals also are an interesting way to stress-test a graphics UI line-rendering capabilities 😉
Start Fiddling Now!
I’ve made a small SmartMS [7] app where you can fiddle with L-System right from any browser (desktop or mobile), along with a few classic presets to get you started:
For the curious ones, timings are listed in the JavaScript console, f.i. hit ctrl+shift+J in Chrome to bring it up.
Now let’s get under the hood!
Applying L-System grammar
Below is the source code for applying a set of grammar rules to an axiom. They’re implemented as a simple set of helper methods to an array of L-System rules.
Let’s suppose you want to generate the Heighway Dragon [9] up to iteration 12, that can be done with just
var rules : TLSystemRules; rules.Add('X', 'X+YF+'); rules.Add('X', '-FX-Y'); var dragon := rules.Apply('FX', 12);
As you see the helper approach allows to keep the code very simple. As to what can be done with the “dragon” string that’ll be topic for part 2 😉
I’ll leave you with the unit that allows the above code to work it magic.
unit LSystem; interface type TLSystemRule = record Predecessor : String; Successor : String; end; TLSystemRules = array of TLSystemRule; TLSystemRulesHelper = helper for TLSystemRules procedure AddRule(const predecessor, successor : String); function Apply(const axiom : String) : String; overload; function Apply(const axiom : String; iterations : Integer) : String; overload; end; implementation { TLSystemRulesHelper } procedure TLSystemRulesHelper.AddRule(const predecessor, successor : String); var r : TLSystemRule; begin r.Predecessor := predecessor; r.Successor := successor; Self.Add(r); end; function TLSystemRulesHelper.Apply(const axiom : String) : String; var i : Integer; s : String; rule : TLSystemRule; begin for i := Low(axiom) to High(axiom) do begin s := axiom[i]; for rule in Self do begin if s = rule.Predecessor then begin s := rule.Successor; break; end; end; Result += s; end; end; function TLSystemRulesHelper.Apply(const axiom : String; iterations : Integer) : String; begin Result := axiom; while iterations > 0 do begin Result := Apply(Result); Dec(iterations); end; end;