Windy Random Fractal Trees

Posted to site: 24/03/19

Continuing on the theme of frac­tals, I was in­spired by a Coding Train video to try my hand at draw­ing frac­tal trees us­ing the fan­tas­tic p5.js li­brary for Javascript. To get a more nat­ural re­sult I in­tro­duced some ran­dom­ness in a va­ri­ety of places in the al­go­rithm, and changed the paint­brush as I drew fur­ther along the tree. To give the trees some life I sim­u­lated the ef­fect of wind act­ing on the trees.

What is a Fractal Tree?

The best way to get a feel for what a frac­tal tree is, is to have a go at draw­ing your own. To this end, I en­cour­age you to go and play with the sta­tic frac­tal tree gen­er­a­tor that I have cre­ated as part of this pro­ject. To un­der­stand the ba­sic de­f­i­n­i­tion bet­ter make sure you turn down the branch length vari­a­tion to 0.

A basic fractal tree with no randomness
A ba­sic frac­tal tree with no ran­dom­ness

Formally, a frac­tal tree can be seen as the in­vari­ant set of an it­er­ated func­tion sys­tem. Intuitively, we can draw a frac­tal tree by first draw­ing a branch of some length di­rectly up­wards. We then draw two scaled down copies of the frac­tal tree at an­gles \(\alpha\) and \(-\alpha\) (say \(\alpha=\pi/6\)). It may seem as though this de­f­i­n­i­tion is tau­to­log­i­cal but in fact it does give us a math­e­mat­i­cally well-de­fined set.

Indeed, for any scale fac­tor this is al­ways well-de­fined but is only a bounded set when the scale fac­tor is less than 1. If the scale fac­tor is big­ger than a half then we would need an in­fi­nite amount of ink to draw this im­age. More­over, due to the na­ture of re­cur­sion in com­put­ing, it would take an in­fi­nite amount of time and re­sources to draw this com­pu­ta­tion­ally re­gard­less of the scale fac­tor. To cre­ate a good ap­prox­i­ma­tion of the frac­tal tree, we stop draw­ing once new branches be­comes too small to no­tice (say 4 pix­els long).

For a more vi­sual demon­stra­tion of this de­f­i­n­i­tion and a guide to cod­ing this draw­ing al­go­rithm in p5.js please watch this fan­tas­tic video by The Coding Train.

Introducing Randomness

These im­ages are very com­pelling and re­veal some very in­ter­est­ing pat­terns. How­ever, from an artis­tic per­spec­tive they lack the nat­ural im­per­fec­tions that one would ex­pect from a real tree. To rem­edy this and pro­vide scope for artis­tic ex­per­i­men­ta­tion, I felt it nec­es­sary to in­tro­duce some ran­dom el­e­ments to this de­f­i­n­i­tion.

Number of branches

At each level of the tree we draw a ran­dom num­ber of branches. More­over, the av­er­age num­ber of branches in­creases log­a­rith­mi­cally with each level of the tree. In this al­go­rithm, the num­ber of branches is cho­sen uni­formly at ran­dom from the in­te­gers be­tween \(2\) and \(\text{floor}(\log(level))+3\).

Branching an­gle

Now that we have a ran­domly cho­sen num­ber of branches we could space them equally over a given an­gle range. To in­tro­duce more ran­dom­ness, and cre­ate more nat­ural look­ing im­ages, the an­gle of ro­ta­tion for each branch is cho­sen again at ran­dom within a given range. How­ever, this can some­times lead to lop­sided trees where both ini­tial branches are cho­sen on the left side of the main trunk. To al­le­vi­ate this, ran­dom num­bers are cho­sen at ran­dom from half the range and then branches are drawn al­ter­nately on the left and right side.

Branch length

Finally, the length of each branch is cho­sen at ran­dom from a Gaussian dis­tri­b­u­tion. If branches at the cur­rent level would usu­ally be \(l\) then the mean of this dis­tri­b­u­tion is \(l\) and the stan­dard de­vi­a­tion is \(\sigma\cdot l\) where \(\sigma\) is some con­trol­lable pa­ra­me­ter. An al­ter­na­tive tech­nique would be set the mean equal to the length of the pre­vi­ous branch.

Drawing Techniques

In na­ture, leaves are usu­ally sig­nif­i­cantly thin­ner than the main trunk and so to cre­ate a more nat­ural pic­ture we de­crease the stroke weight and opac­ity at each level by some fixed ra­tio. This cre­ates a less busy, more nat­ural look­ing im­age.

Moreover, leaves are gen­er­ally a dif­fer­ent colour to the trunk and main branches. To this end, we can colour the first \(n \) lev­els in one colour and the re­main­ing lev­els in an­other colour. This vastly in­creases the artis­tic pos­si­bil­i­ties.

Simulating Wind

In or­der to breathe life into these trees, I de­cided to sim­u­late the ef­fect of wind on these struc­tures. In or­der to do this each branch of the tree is sub­jected to three forces:

These force acts cu­mu­la­tively on each branch which is given a mass based on its level in the tree. One could give each branch a mass based on its length but this would in­volve costly di­vi­sion. To gen­er­ate a frac­tal tree and sim­u­late this wind al­go­rithm click here. Note this is quite a re­source in­ten­sive sim­u­la­tion so mo­bile de­vices may strug­gle.

Finished Result and Next Steps

If you’d like to play with this al­go­rithm and make some artis­tic frac­tal trees please check out my sta­tic gen­er­a­tor and windy gen­er­a­tor, which are im­ple­mented in the p5.js li­brary. Note these run in Javascript en­tirely in the browser and so is not the most per­for­mant gen­er­a­tor. Be­low are some ex­am­ples I have made with the gen­er­a­tor.

Example of a random fractal tree
Example of a random fractal tree
Some ex­am­ples of ran­dom frac­tal trees

Example of a random fractal tree
Example of a random fractal tree
Some ex­am­ples of ran­dom frac­tal trees

There is cer­tainly much more to do with this gen­er­a­tor. For ex­am­ple, we could: