#### Brian Douglas

An Irish Software Engineer working in Edinburgh.

Fractals show the beauty of numbers. There are many famous fractals, which are often named after European mathematicians. You may have heard of Sierpinski's Triangle, the Mandelbrot Set, and the Koch Curve. These are all fractal patterns.

I'm going to show you how to create the Koch Snowflake using the Canvas element.

The Koch Snowflake is not technically a fractal. It is a shape made up of three Koch Curves. When these Koch Curves are positioned correctly they create a Koch Snowflake.

Let's create the function that draws a Koch Curve. We'll name it koch.

```
const koch = (a, b, limit = 3) => {
let [dx, dy] = [b.x - a.x, b.y - a.y]
let dist = Math.sqrt(dx * dx + dy * dy)
let unit = dist / 3
let angle = Math.atan2(dy, dx)
//This will be the triangular shape that makes the 'points' on the snowflake
let p1 = {
x: a.x + dx / 3,
y: a.y + dy / 3
}
let p3 = {
x: b.x - dx / 3,
y: b.y - dy / 3
}
let p2 = {
x: p1.x + Math.cos(angle - Math.PI / 3) * unit,
y: p1.y + Math.sin(angle - Math.PI / 3) * unit
}
if (limit > 0) {
// Decrease limit each time it's called
koch(a, p1, limit - 1)
koch(p1, p2, limit - 1)
koch(p2, p3, limit - 1)
koch(p3, b, limit - 1)
} else {
context.beginPath()
context.moveTo(a.x, a.y)
context.lineTo(p1.x, p1.y)
context.lineTo(p2.x, p2.y)
context.lineTo(p3.x, p3.y)
context.lineTo(b.x, b.y)
context.stroke()
}
}
```

The Koch function above takes two starting coordinates. These should be in the form of `{x: 90, y: 90}`

. We'll use these coordinates to plot where the triangular 'curve' should be placed. You can see the coordinates for the triangle's points defined as `p1,p2,p3`

inside the function.

The function will be called recursively, to create the fractal. We must ensure that an infinite loop is not formed. To prevent this we pass in a default limit of recursion. This can be changed. Changing it to a higher number, will add little visual difference.

To use this function and create the Koch Snowflake, we must add some more boilerplate code.

```
(() => {
// Create canvas element, that we will draw on
const canvas = document.createElement('canvas')
document.body.appendChild(canvas)
const context = canvas.getContext('2d')
const width = canvas.width = 420
const height = canvas.height = 420
// The starting cordinates, basically tilting the Koch Curve
// so that when we add three together they form the snowflake
const startingPoints = {
p1: {
x: 0,
y: -150
},
p2: {
x: 150,
y: 100
},
p3: {
x: -150,
y: 100
}
}
// Draw relative to center of the screen
context.translate(.5 * width, .5 * height)
// add a default limit of three as we don't want an infinite loop
const koch = (a, b, limit = 3) => {
let [dx, dy] = [b.x - a.x, b.y - a.y]
let dist = Math.sqrt(dx * dx + dy * dy)
let unit = dist / 3
let angle = Math.atan2(dy, dx)
//This will be the triangular shape that makes the 'point' of the curve
let p1 = {
x: a.x + dx / 3,
y: a.y + dy / 3
}
let p3 = {
x: b.x - dx / 3,
y: b.y - dy / 3
}
let p2 = {
x: p1.x + Math.cos(angle - Math.PI / 3) * unit,
y: p1.y + Math.sin(angle - Math.PI / 3) * unit
}
if (limit > 0) {
// Decrease limit each time it's called
koch(a, p1, limit - 1)
koch(p1, p2, limit - 1)
koch(p2, p3, limit - 1)
koch(p3, b, limit - 1)
} else {
context.beginPath()
context.moveTo(a.x, a.y)
context.lineTo(p1.x, p1.y)
context.lineTo(p2.x, p2.y)
context.lineTo(p3.x, p3.y)
context.lineTo(b.x, b.y)
context.stroke()
}
}
// draw the shape using our predefined co-ordinates
koch(startingPoints.p1, startingPoints.p2)
koch(startingPoints.p2, startingPoints.p3)
koch(startingPoints.p3, startingPoints.p1)
})()
```

If you have followed these examples correctly you should have something that looks like the following codepen http://codepen.io/BrianDGLS/pen/GZdLjj.

It's true. I left out a lot of detail here. Fractals are both simple and complex, which makes them hard to explain. I can show you quite easily how to make a fractal, but explaining why certain numbers and methods work is much harder. I have been playing around with canvas fractals for a while and I am only just starting to get a feel for it.

If you are intrigued and want to learn more, I recommend looking at the mathematics behind fractals, as opposed to how to code them. The prior will lead to the latter.

I recommend checking out Numberphile on YoutTube. This channel does an awesome job of explaining complex maths. It's also a great source of inspiration for writing code.

Want a challenge? Using the methods I introduced above, try creating the Sierpinski Triangle. If you manage to do it post the result as a comment.

*Originally posted on hard-coded.com*

Funny, I was just playing with fractals on canvas the other day. Specifically the Barnsley Fern. I think it's a very interesting way to build and understand fractal structures. Also, it's great to see them build up pixel per pixel.

Here's my quick & dirty implementation.

Nice, what is the

`math`

library you are using in that example?I had forgotten I did a few things in the HTML. Obviously create the

`#canvas`

element and import the math library.The math library I used is mathjs which I use for random number generation and matrix multiplication.

As for my

`setInterval`

callback, the`transform`

call flips the canvas and translates it so that the origin is at the bottom center. The`*50`

in the`fillRect`

call is just an arbitrary scaling factor.I'm editing to add comments, I just banged this out one night to see if I could remember Barnsley's Fern from my CG classes.

OK, so I toyed around with this a bit more and made into a codepen right here: codepen.io/loderunnr/pen/YNyNeq

I couldn't quite get the transformations for the Koch Snowflake, but I still got a pretty nice snowflake going. I also did the Sierpinski Triangle for a laugh. Check out the commented transformations at the start of the JS.

Nice one!, looks good.

I would humbly suggest not using const unless it's for a value where the variable name would normally be in ALL_CAPS. Const reduces the code's readability - as one is mentally parsing the code, seeing const makes you stop and think, "ooh, this is special and unchanging," only to discover it's just a plain object or function. Just use let unless you really, really need to make sure the value doesn't ever change, and you never want to reassign that variable name.