In this post we will look further into L Systems and see how they can be used to tree and fern liek structures using generativepy. We will make use of the simple turtle system developed in a previous post.

## Extending our L System grammar

We will start by creating a simple binary tree like this:

This pattern is the 6th generation of a pattern that starts out as a simple Y shape. Unlike simpler L Systems, it exhibits branching. There are 64 “leaves” in the images. Starting from the first generation (a Y shape) which has 2 leaves, the number of leaves doubles on each generation (2 to the power 6 is 64).

To implement branching, we need to add two extra characters to our L System grammar:

`[`

doesn’t draw anything, but it saves the current turtle position and heading`]`

also doesn’t draw anything, but restores the previous turtle position and heading.

So the string `[ABC]XYZ`

saves the initial position then draws `ABC`

(whatever that might be). It then restores the previous position, and draws `XYZ`

starting from the original position and heading. Notice that `ABC`

and `XYZ`

just represent whatever real operations you might want to perform.

The save and restore operations use a stack, so you can save multiple positions, and they will be restored in the reverse order.

## Binary tree parameters

Here are the rules for the binary tree:

```
F becomes G[+F]-F
G becomes GG
+ becomes +
- becomes -
[ becomes [
] becomes ]
```

`F`

and `G`

both draw a line length 10. `+`

and `-`

turn left or right by 45 degrees (`pi/4`

).

It is worth looking at the first pass. The initial string `F`

becomes `G[+F]-F`

. Here is what this draws:

Imagine we start of at point A, with the turtle heading upwards.

`G`

moves 10 units upwards to point B`[`

saves the current position (B) and heading (upwards)`+F`

turns the turtle 45 degrees left and draws 10 units to point C`]`

restores the previous position. The turtle is placed back at point B, heading upwards, without drawing anything`-F`

turns the turtle 45 degrees right and draws 10 units to point D

## The code

Here is the binary tree Python code:

```
from generativepy import drawing
from generativepy.drawing import makeSvg
from generativepy.color import Color
from turtle import Turtle
import math
AXIOM = 'F'
RULES = { 'F' : 'G[+F]-F',
'G' : 'GG',
'[' : '[',
']' : ']',
'+' : '+',
'-' : '-' }
ITERATIONS = 6
ANGLE = math.pi/4
LENGTH = 10
SIZE=800
def lsystem(start, rules):
out = ''
for c in start:
s = rules[c]
out += s
return out
def draw(canvas):
s = AXIOM
for i in range(ITERATIONS):
s = lsystem(s, RULES)
turtle = Turtle(canvas)
canvas.stroke(Color('darkblue'))
canvas.strokeWeight(2)
turtle.moveTo(SIZE/2, SIZE-10)
turtle.left(math.pi/2)
for c in s:
if c=='F':
turtle.forward(LENGTH)
if c=='G':
turtle.forward(LENGTH)
elif c=='[':
turtle.push()
elif c==']':
turtle.pop()
elif c=='+':
turtle.left(ANGLE)
elif c=='-':
turtle.right(ANGLE)
makeSvg("lsystem-binary-tree.svg", draw, pixelSize=(SIZE, SIZE))
```

The main things to note here are:

- The turtle is moved to position
`(SIZE/2, SIZE-10)`

, the centre-bottom of the canvas, and turned to point upwards, just after the turtle is created. - We have added the
`[`

and`]`

cases using the existing`Turtle`

methods`push`

and`pop`

.

Here is the result:

The trees are all at the same scale, except the sixth iteration, which is scaled down very slightly (to 75% of its original size) to fit.

## A more realistic plant

We will modify the previous code slightly to create a more realistic looking L System plant.

The first rule is chnaged to:

```
F becomes G+[[F]-F]-G[-GF]+F
```

and the angle is changed to 20 degrees. This gives the following basic shape (ie the shape after 1 iteration):

You can follwo this through, step by step, like we did for the binary tree, if you wish. The shape creates after 6 iterations is:

The final code is below. All that has really changed are the rules and angle, a bit of adjustment of the size and position, and all importantly making the plant green instead of blue.

```
from generativepy import drawing
from generativepy.drawing import makeSvg
from generativepy.color import Color
from turtle import Turtle
import math
AXIOM = 'F'
RULES = { 'F' : 'G+[[F]-F]-G[-GF]+F',
'G' : 'GG',
'[' : '[',
']' : ']',
'+' : '+',
'-' : '-' }
ITERATIONS = 6
ANGLE = 20*math.pi/180
LENGTH = 5
SIZE=800
def lsystem(start, rules):
out = ''
for c in start:
s = rules[c]
out += s
return out
def draw(canvas):
s = AXIOM
for i in range(ITERATIONS):
s = lsystem(s, RULES)
turtle = Turtle(canvas)
canvas.stroke(Color('darkgreen'))
canvas.strokeWeight(2)
turtle.moveTo(SIZE/4, SIZE-10)
turtle.left(75*math.pi/180)
for c in s:
if c=='F':
turtle.forward(LENGTH)
if c=='G':
turtle.forward(LENGTH)
elif c=='[':
turtle.push()
elif c==']':
turtle.pop()
elif c=='+':
turtle.left(ANGLE)
elif c=='-':
turtle.right(ANGLE)
makeSvg("lsystem-tree.svg", draw, pixelSize=(SIZE, SIZE))
```