Elm – fun with L-System (Part 4)

Series:

  1. Algae
  2. Pythago­ras Tree
  3. Can­tor Dust
  4. Koch Curve (this)
  5. Sier­pin­ski Tri­an­gle
  6. Drag­on Curve
  7. Frac­tal Plant

Last time out we imple­mented the Can­tor Dust exam­ple from the L-Sys­tem wikipedia page. Now, let’s con­tinue our jour­ney and see how we can imple­ment the Koch Curve exam­ple in Elm.

 

Example 4 : Koch Curve

Once again, we will start by defin­ing our L-Sys­tem:

image

From here, there are a lot of sim­i­lar­i­ties with our imple­men­ta­tion for Part 2, so time for a minor refac­tor!

We’ll add a shared Path mod­ule, and move the com­mon abstrac­tions and helper func­tions there:

image

Over the course of the series, we’ll add to this com­mon mod­ule to help han­dle oth­er aspects of draw­ing our L-Sys­tems.

 

For the Koch Curve, the only thing we real­ly need to imple­ment is the dis­play func­tion to han­dle ‘F’, ‘–’ and ‘+’:

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

So this was what I end­ed up with as a 1st pass:

image

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

The most impor­tant bit of code is here:

image

where we imple­ment­ed the log­ic for:

  • F’ : draw a line seg­ment
  • –‘ :  turn left 90 degrees
  • +’ : turn right 90 degrees

in a left fold over the cur­rent state, using the start­ing posi­tion (0, 0) and rota­tion angle 0 (radi­ans).

But, what’s this can­vasArea that’s passed along?

Aha, good, you caught me! I’ve secret­ly added a lit­tle some­thing to the Path mod­ule:

image

These are to help me track the area that has been drawn on so that I can use this infor­ma­tion to scale down and move the com­plet­ed path lat­er on so that it fits inside the col­lage and is cen­tred.


canvas_area

When­ev­er a new seg­ment has been added the end­ing posi­tion is used to expand the can­vas area:

image

At the end, we work out the scale fac­tor, and move the path to the cen­tre of the col­lage:

image

 

As it turns out, much of what’s in the dis­play func­tion is the same across most of the exam­ples, so let’s refac­tor and move it into the Path mod­ule:

image

and our Koch Curve imple­men­ta­tion becomes much sim­pler:

image

 

Run­ning this exam­ple in Elm Reac­tor I can get the demo to gen 6, before the ren­der­ing time starts to go up notice­ably.

koch_curve

 

Live Demo (here)

Use LEFT and RIGHT arrow keys to evolve/devolve the L-Sys­tem.

 

Source Code (here)

 

 

Next : Sier­pin­s­ki Tri­an­gle

 

Links