Hello,

Recording of my Elm talk at Polyconf this year is available now.

Series:

- Algae
- Pythagoras Tree
- Cantor Dust
- Koch Curve
- Sierpinski Triangle
- Dragon Curve
- Fractal Plant (this)

Last time out we implemented the *Dragon Curve *example from the L-System wikipedia page. Now, we’re finally at the end of our journey, let’s see how we can implement the *Fractal Plant *example in Elm.

Let’s start by defining our L-System:

What’s interesting about the *Fractal Plant *is that it combines elements from *Pythagoras Tree* (the use of a stack) and other L-Systems we looked at recently.

Here’s how it looks, by gen 7 the plant looks pretty good!

In fact, with the implementation we ended up with, we can use it to support any number of L-Systems so long:

- ‘F’ is the only symbol that means “draw forward”
- we can programmatically change the angle for ‘–’ and ‘+’ (easy!)

with that, let’s take a couple of the examples from LSystemBot’s tweets and see them in action!

So that’s it guys, hope you’ve enjoyed this series! Please let me know via the comments if you like to see more mini-series like this one.

Use LEFT and RIGHT arrow keys to evolve/devolve the L-System.

Series:

- Algae
- Pythagoras Tree
- Cantor Dust
- Koch Curve
- Sierpinski Triangle
- Dragon Curve (this)
- Fractal Plant

Last time out we implemented the *Sierpinski Triangle *example from the L-System wikipedia page. Now, let’s continue our journey and see how we can implement the (rather impressive sounding) *Dragon Curve* example in Elm.

First, let’s define our L-System:

Again, thanks to the work we did in Part 4, our work here is rather simple:

which is a pretty straight translation of:

- ‘F’ : draw forward
- ‘–’ : turn left 90 degrees
- ‘+’ : turn right 90 degrees
- ‘X’ and ‘Y’ : ignore

Unlike the other L-Systems, this one grows much slower and as it slows it does make a nice picture!

Use LEFT and RIGHT arrow keys to evolve/devolve the L-System.

*Next : Fractal Plant*

Series:

- Algae
- Pythagoras Tree
- Cantor Dust
- Koch Curve
- Sierpinski Triangle (this)
- Dragon Curve
- Fractal Plant

Last time out we implemented the *Koch Curve *example from the L-System wikipedia page. Now, let’s continue our journey and see how we can implement the *Sierpinski Triangle* example in Elm.

First, let’s define our L-System:

Since we have done a lot of the heavy lifting in the last post (recall the Path module we created), we actually don’t have much to do here.

The only thing of interest here is that both ‘A’ and ‘B’ mean “draw forward”, but need to be represented different for the growth rules.

As far as I know, (please correct me in the comments if I’m wrong about this) there is no way to handle both symbols using *case..of *here, e.g.

case sym of

‘A’ | ‘B’ –> …

similar to how one would do in F#:

match sym of

| ‘A’ | ‘B’ –> …

| ‘+’ –> …

| ‘–‘ –> …

Hence why I opted for a multi-way if statement here instead.

Here’s how it looks, feel free to try it out yourself via the live demo links below.

But wait, the L-System wikipedia page also mentions a second way to draw the *Sierpinski Triangle*:

So, let’s implemented this as well, as v2.

When I used the suggested 120 degrees, I got an upside-down triangle. So instead, I used –120 degrees here:

Yup, it’s basically a carbon copy of the first version, except for a different value for *angle* plus different symbols.

Why are the examples not consistent with the choice of symbols for “draw forward”? One wonders…

Anyhow, here’s how it looks, which you can also try out via the live demo links below.

Use LEFT and RIGHT arrow keys to evolve/devolve the L-System.

*Next : Dragon Curve*

Series:

- Algae
- Pythagoras Tree
- Cantor Dust
- Koch Curve (this)
- Sierpinski Triangle
- Dragon Curve
- Fractal Plant

Last time out we implemented the *Cantor Dust *example from the L-System wikipedia page. Now, let’s continue our journey and see how we can implement the *Koch Curve* example in Elm.

Once again, we will start by defining our L-System:

From here, there are a lot of similarities with our implementation for Part 2, so time for a minor refactor!

We’ll add a shared Path module, and move the common abstractions and helper functions there:

Over the course of the series, we’ll add to this common module to help handle other aspects of drawing our L-Systems.

For the *Koch Curve*, the only thing we really need to implement is the **display **function to handle ‘F’, ‘–’ and ‘+’:

“Here, F means “draw forward”, + means “turn left 90 degrees”, and – means “turn right 90 degrees”..”

So this was what I ended up with as a 1st pass:

OK, so that was a lot of code to digest, so let’s break it down a bit.

The most important bit of code is here:

where we implemented the logic for:

- ‘F’ : draw a line segment
- ‘–‘ : turn left 90 degrees
- ‘+’ : turn right 90 degrees

in a left fold over the current state, using the starting *position* *(0, 0)* and *rotation angle 0 *(radians).

But, what’s this *canvasArea *that’s passed along?

Aha, good, you caught me! I’ve secretly added a little something to the *Path *module:

These are to help me track the area that has been drawn on so that I can use this information to scale down and move the completed path later on so that it fits inside the collage and is centred.

Whenever a new segment has been added the ending position is used to expand the canvas area:

At the end, we work out the scale factor, and move the path to the centre of the collage:

As it turns out, much of what’s in the *display *function is the same across most of the examples, so let’s refactor and move it into the *Path *module:

and our *Koch Curve* implementation becomes much simpler:

Running this example in Elm Reactor I can get the demo to gen 6, before the rendering time starts to go up noticeably.

Use LEFT and RIGHT arrow keys to evolve/devolve the L-System.

*Next : Sierpinski Triangle*

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.