<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Iner Garcia Rodriguez</title>
    <description>The latest articles on DEV Community by Iner Garcia Rodriguez (@inergarcia).</description>
    <link>https://dev.to/inergarcia</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F809089%2F4d3cab9e-361b-483a-b1f8-8fb3f5528b25.jpeg</url>
      <title>DEV Community: Iner Garcia Rodriguez</title>
      <link>https://dev.to/inergarcia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/inergarcia"/>
    <language>en</language>
    <item>
      <title>Playing with Fractals</title>
      <dc:creator>Iner Garcia Rodriguez</dc:creator>
      <pubDate>Fri, 04 Feb 2022 04:22:16 +0000</pubDate>
      <link>https://dev.to/inergarcia/playing-with-fractals-1463</link>
      <guid>https://dev.to/inergarcia/playing-with-fractals-1463</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LIk4pa1F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xixe24jsfx7mf0m0gtsq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LIk4pa1F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xixe24jsfx7mf0m0gtsq.jpg" alt="Image description" width="880" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are a lover of fractals, analytical geometry and programming, in this article you will learn how to draw fractals using Java Script.&lt;/p&gt;

&lt;p&gt;Fractals are geometric figures formed by repetitions of the same pattern a large number of times. A fractal gives us a graphical representation of what is commonly known in programming as &lt;strong&gt;recursion&lt;/strong&gt;. In this post we will program some of the most famous fractals.&lt;/p&gt;

&lt;h2&gt;
  
  
  Auxiliary functions
&lt;/h2&gt;

&lt;p&gt;Before getting into the matter, I will show you some complementary functions and libraries that were used to simplify the algorithms.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The external library &lt;a href="http://victorjs.org/"&gt;Victor&lt;/a&gt; was used, which has a set of necessary functions when working with vectors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;quque&lt;/code&gt; class was created, which consists of a very basic implementation of what a &lt;strong&gt;queue&lt;/strong&gt; would be.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const queue = function() {
    this.q = []

    this.push = function(ele) {
        this.q.push(ele)
    }

    this.empty = function() {
        return this.q.length === 0
    }

    this.top = function() {
        if(!this.empty())
            return this.q[0]
        return null
    }

    this.pop = function() {
        if(!this.empty())
            return this.q.shift()
        return null
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;A &lt;code&gt;paint.js&lt;/code&gt; file was created which contains a set of methods to simplify the process when "drawing" on the &lt;code&gt;html&lt;/code&gt; &lt;code&gt;canvas&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const resetCanvas = (ctx, width, height) =&amp;gt; {
    ctx.fillStyle = '#071a52'
    ctx.fillRect(0, 0, width, height)
    ctx.strokeStyle = "#f0f0f0"
}

export const drawLineVector = (ctx, v) =&amp;gt; {

    for(let i = 0; i &amp;lt; v.length - 1; i++){
        ctx.beginPath()
        ctx.moveTo(v[i].x, v[i].y)
        ctx.lineTo(v[i+1].x, v[i+1].y)
        ctx.stroke()
        ctx.closePath()
    }
}

export const drawLine2Point = (ctx, p1, p2) =&amp;gt; {
    ctx.beginPath()
    ctx.moveTo(p1.x, p1.y)
    ctx.lineTo(p2.x, p2.y)
    ctx.stroke()
    ctx.closePath()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sierpinski triangle
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y79_p9q8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e3z3x8sil8ic8qk41gwu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y79_p9q8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e3z3x8sil8ic8qk41gwu.png" alt="Image description" width="700" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As shown in the figure, the fractal is achieved by repeating the same triangle with smaller dimensions.&lt;/p&gt;

&lt;p&gt;The following figure will help us understand the mathematical process:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Biodocbx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hkhquhmg2y8xe9cc3rha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Biodocbx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hkhquhmg2y8xe9cc3rha.png" alt="Image description" width="531" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We create the triangle P1P2P3&lt;/li&gt;
&lt;li&gt;We calculate the midpoints P1', P2' and P3'&lt;/li&gt;
&lt;li&gt;We create the triangles P1P1'P3', P1'P2P2'and P2'P3P3'&lt;/li&gt;
&lt;li&gt;We repeat the process with the new triangles created.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is the code:&lt;/p&gt;

&lt;p&gt;We import the necessary dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Victor from 'victor'
import {drawLine2Point} from './paint'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create a class &lt;code&gt;Triangle&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Triangle = function(p1, p2, p3, tag) {
    this.p1 = p1
    this.p2 = p2
    this.p3 = p3
    this.tag = tag
    this.generated = false

    this.show = function(ctx){
        if(this.tag === 'root'){
            drawLine2Point(ctx, this.p1, this.p2)
            drawLine2Point(ctx, this.p2, this.p3)
            drawLine2Point(ctx, this.p3, this.p1)
        }else if(this.tag === 't1'){
            drawLine2Point(ctx, this.p2, this.p3)
        }else if(this.tag === 't2'){
            drawLine2Point(ctx, this.p3, this.p1)
        }else if(this.tag === 't3'){
            drawLine2Point(ctx, this.p1, this.p2)
        }
    }

    this.T1 = function() {
        let t1_p1 = new Victor(this.p1.x, this.p1.y)
        let t1_p2 = new Victor((this.p1.x + this.p2.x) / 2, (this.p1.y + this.p2.y) / 2)
        let t1_p3 = new Victor((this.p1.x + this.p3.x) / 2, (this.p1.y + this.p3.y) / 2)
        let t1 = new Triangle(t1_p1, t1_p2, t1_p3, 't1')
        return t1
    }

    this.T2 = function() {
        let t2_p1 = new Victor((this.p1.x + this.p2.x) / 2, (this.p1.y + this.p2.y) / 2)
        let t2_p2 = new Victor(this.p2.x, this.p2.y)
        let t2_p3 = new Victor((this.p2.x + this.p3.x) / 2, (this.p2.y + this.p3.y) / 2)
        let t2 = new Triangle(t2_p1, t2_p2, t2_p3, 't2')
        return t2
    }

    this.T3 = function() {
        let t3_p1 = new Victor((this.p1.x + this.p3.x) / 2, (this.p1.y + this.p3.y) / 2)
        let t3_p2 = new Victor((this.p2.x + this.p3.x) / 2, (this.p2.y + this.p3.y) / 2)
        let t3_p3 = new Victor(this.p3.x, this.p3.y)
        let t3 = new Triangle(t3_p1, t3_p2, t3_p3, 't3')
        return t3
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally we create the function that generates the fractal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const Sierpinski = (ctx, p1, p2, p3, n) =&amp;gt; {
    let T = []
    let root = new Triangle(p1, p2, p3, 'root')
    T[0] = root

    while(n--){
        for(let i = T.length - 1; i &amp;gt;= 0; i--){
            if(!T[i].generated){
                T.push(T[i].T1())
                T.push(T[i].T2())
                T.push(T[i].T3())
                T[i].generated = true
            }
        }
    }

    for(let i = 0; i &amp;lt; T.length; i++){
        T[i].show(ctx)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function receives 5 parameters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;ctx&lt;/code&gt; Reference to the context of the canvas object &lt;code&gt;canvas.getContext('2d')&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;p1&lt;/code&gt; Object of type &lt;code&gt;Victor&lt;/code&gt; that contains the coordinates of point p1.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;p2&lt;/code&gt; Object of type &lt;code&gt;Victor&lt;/code&gt; that contains the coordinates of point p2.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;p3&lt;/code&gt; Object of type &lt;code&gt;Victor&lt;/code&gt; that contains the coordinates of point p3.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;n&lt;/code&gt; Integer representing the number of levels.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is how our fractal will look:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xelkSAga--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rywc8xhfzhh38vibvwuv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xelkSAga--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rywc8xhfzhh38vibvwuv.png" alt="Image description" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dragon curve
&lt;/h2&gt;

&lt;p&gt;This fractal is built following the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Given a segment AB, an isosceles right triangle with base AB is constructed.&lt;/li&gt;
&lt;li&gt;Segment AB is deleted.&lt;/li&gt;
&lt;li&gt;The procedure is repeated a certain number of times.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The following image shows the process for the first 3 levels.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dv0P74cM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e9uc35whczv7n5z4ksbb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dv0P74cM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e9uc35whczv7n5z4ksbb.png" alt="Image description" width="699" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the code:&lt;/p&gt;

&lt;p&gt;We import the necessary dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Victor from 'victor'
import {queue} from './queue'
import {drawLine2Point} from './paint'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create an auxiliary function that returns the point between A and B that forms an isosceles and right triangle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mP = (p1, p2) =&amp;gt; {

    return new Victor(
        (p1.x + p2.x + p1.y - p2.y) / 2, 
        (p2.x - p1.x + p1.y + p2.y) / 2)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create the function that generates the fractal using a BFS algorithm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let Q = new queue();

export const dragon_bfs = (ctx, a, b, n) =&amp;gt; {
    let line = {
        p1: a,
        p2: b
    }

    if(!n){
        drawLine2Point(ctx, line.p1, line.p2)
    }else{
        Q.push(line)
        let N = Math.pow(2, n) - 1

        while(N){
            let l = Q.top()
            Q.pop()

            let l1 = {
                p1: l.p1,
                p2: mP(l.p1, l.p2)
            } 

            let l2 = {
                p1: l.p2,
                p2: mP(l.p1, l.p2)
            }
            Q.push(l1)
            Q.push(l2)
            N--
        }
        N = Math.pow(2, n)

        while(N){
            drawLine2Point(ctx, Q.top().p1, Q.top().p2)
            Q.pop()
            N--
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function receives 4 parameters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;ctx&lt;/code&gt; Reference to the context of the canvas object &lt;code&gt;canvas.getContext('2d')&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;a&lt;/code&gt; Object of type &lt;code&gt;Victor&lt;/code&gt; that contains the coordinates of point a.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;b&lt;/code&gt; Object of type &lt;code&gt;Victor&lt;/code&gt; that contains the coordinates of point b.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;n&lt;/code&gt; Integer representing the number of levels.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is how our fractal will look:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yT5rHHQI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ltsb8bngu0bvhvghmb83.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yT5rHHQI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ltsb8bngu0bvhvghmb83.png" alt="Image description" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Von Kock's curve
&lt;/h2&gt;

&lt;p&gt;Discovered by the mathematician Helge Von Koch in 1904. The curve is constructed as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Given a segment AB is divided into three equal parts (3 segments).&lt;/li&gt;
&lt;li&gt;With the middle segment we build an equilateral triangle.&lt;/li&gt;
&lt;li&gt;The process is repeated for each of the smaller segments.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's see the process in the following figure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mbGmL8Sn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/df8njr2gqwll2at3hqd8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mbGmL8Sn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/df8njr2gqwll2at3hqd8.png" alt="Image description" width="700" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's see for the first two levels:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hBwjIVIE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k63mr2bfyeic59luqz8z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hBwjIVIE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k63mr2bfyeic59luqz8z.png" alt="Image description" width="700" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the code:&lt;/p&gt;

&lt;p&gt;We import the dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {drawLineVector} from './paint'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will create two helper functions.&lt;/p&gt;

&lt;p&gt;The first to determine the points at 1/3 and 2/3 of the segment AB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getPoint = (a, b, t) =&amp;gt; {
    return {
        x: a.x * (1 - t) + b.x * t,
        y: a.y * (1 - t) + b.y * t 
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function receives 3 parameters: the points a and b of the segment to be partitioned and a proportion t, in such a way that when &lt;code&gt;t=1/3&lt;/code&gt; returns the point at &lt;code&gt;1/3&lt;/code&gt; of the segment and when &lt;code&gt;t=2/3&lt;/code&gt; returns the point 2/3 of the segment.&lt;/p&gt;

&lt;p&gt;The second function receives three parameters: a point &lt;code&gt;p&lt;/code&gt;, a point &lt;code&gt;c&lt;/code&gt; and an angle differential &lt;code&gt;da&lt;/code&gt; (in radians). What it does is rotate point &lt;code&gt;p&lt;/code&gt; &lt;code&gt;gives&lt;/code&gt; radians about the circle with center &lt;code&gt;c&lt;/code&gt; and radius equal to the distance between point &lt;code&gt;p&lt;/code&gt; and point &lt;code&gt;c&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getCirPoint = (p, c, da) =&amp;gt; {
    let dx = p.x - c.x
    let dy = p.y - c.y
    let r = Math.sqrt(dx*dx + dy*dy)
    let a = Math.atan2(dy, dx)
    a -= da

    let q = {
        x: c.x + r * Math.cos(a),
        y: c.y + r * Math.sin(a)
    }

    return q
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally the function that generates the curve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const pi = Math.PI

export const vonKock = (ctx, a, b, n) =&amp;gt; {
    let P = [a, a, a, a, b]

    P[1] = getPoint(P[0], P[4], 1.0/3.0)
    P[3] = getPoint(P[0], P[4], 2.0/ 3.0)
    P[2] = getCirPoint(P[3], P[1], pi / 3.0)

    if(n &amp;lt;= 1){
        drawLineVector(ctx, P, true)
    }else{
        for(let i = 0; i &amp;lt; P.length - 1; i++)
            vonKock(ctx, P[i], P[i + 1], n-1)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function receives 4 parameters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;ctx&lt;/code&gt; Reference to the context of the canvas object (&lt;code&gt;canvas.getContext('2d')&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;a&lt;/code&gt; Object of type &lt;code&gt;Victor&lt;/code&gt; that contains the coordinates of point a.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;b&lt;/code&gt; Object of type &lt;code&gt;Victor&lt;/code&gt; that contains the coordinates of point b.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;n&lt;/code&gt; Integer representing the number of levels.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is another implementation that returns the same result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const pi = Math.PI
export const vonKock = (ctx, a, b, n) =&amp;gt; {
    let P = [a, a, a, a, b]

    P[1] = {
        x: a.x + (b.x - a.x) / 3,
        y: a.y + (b.y - a.y) / 3
    }

    P[3] = {
        x: b.x + (a.x - b.x) / 3,
        y: b.y + (a.y - b.y) / 3
    }

    P[2] = {
        x: (P[1].x + P[3].x) * Math.cos(pi/3) + (P[3].y - P[1].y)*Math.sin(pi/3),
        y: (P[1].y + P[3].y) * Math.cos(pi/3) - (P[3].x - P[1].x)*Math.sin(pi/3)
    }

    if(n &amp;lt;= 1){
        drawLineVector(ctx, P)
    }else{
        for(let i = 0; i &amp;lt; P.length - 1; i++)
            vonKock(ctx, P[i], P[i + 1], n-1)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how our fractal will look:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BKLY1bkh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3bcq8vzjgygwihmov0b9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BKLY1bkh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3bcq8vzjgygwihmov0b9.png" alt="Image description" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Drawing trees
&lt;/h2&gt;

&lt;p&gt;Now we will create fractals in the shape of trees.&lt;/p&gt;

&lt;p&gt;To create this type of fractals we proceed as follows.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Given a segment AB, two smaller copies are created.&lt;/li&gt;
&lt;li&gt;The new segments are rotated with a certain angle.&lt;/li&gt;
&lt;li&gt;The two segments are translated until they coincide with point B.&lt;/li&gt;
&lt;li&gt;The process is repeated for each segment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The following figure shows the mentioned process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VK2Ca-rE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5lnvaxvx7pzh6w113c9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VK2Ca-rE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5lnvaxvx7pzh6w113c9.png" alt="Image description" width="701" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By varying the new size and each angle of rotation you can create an infinite number of different trees.&lt;/p&gt;

&lt;p&gt;Let's see the code:&lt;/p&gt;

&lt;p&gt;We import the necessary dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Victor from 'victor'
import {drawLine2Point} from './paint'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create a class &lt;code&gt;Branch&lt;/code&gt; which will be a representation of a branch of the tree and has the following properties:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;start&lt;/code&gt; An object of type &lt;code&gt;Victor&lt;/code&gt; that represents the point where the branch begins.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;end&lt;/code&gt; An object of type &lt;code&gt;Victor&lt;/code&gt; that represents the point where the branch ends.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;al&lt;/code&gt; Rotation angle (in radians) of the left (child) branch.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ar&lt;/code&gt; Angle of rotation (in radians) of the right branch (child).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;divl&lt;/code&gt; Left Bundle Branch Growth Factor (child),&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;divr&lt;/code&gt; Right Branch (child) Growth Factor.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Branch = function(start, end, al, ar, divl, divr) {
    this.start = start
    this.end = end
    this.left_angle = al
    this.right_angle = ar
    this.divl = divl
    this.divr = divr
    this.completed = false

    this.show = function(ctx) {
        drawLine2Point(ctx, this.start, this.end)
    }

    this.branchA = function() {
        let dir = new Victor(this.end.x, this.end.y).subtract(this.start) 
        dir.rotate(this.right_angle)
        dir.divide(new Victor(this.divr, this.divr))
        dir.add(this.end)

        let right = new Branch(this.end, dir, this.left_angle, this.right_angle, this.divl, this.divr)
        return right
    }

    this.branchB = function() {
        let dir = new Victor(this.end.x, this.end.y).subtract(this.start) 
        dir.rotate(this.left_angle)
        dir.divide(new Victor(this.divl, this.divl))
        dir.add(this.end)

        let left = new Branch(this.end, dir, this.left_angle, this.right_angle, this.divl, this.divr)
        return left
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally the code that generates the tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const generateTree = (ctx, p1, p2, al, ar, divl, divr, n) =&amp;gt; {
    let T = []
    let root = new Branch(p1, p2, al, ar, divl, divr)
    T[0] = root    

    while(n--){
        for(let i = T.length - 1; i &amp;gt;= 0; i--){
            if(!T[i].completed){
                T.push(T[i].branchA())
                T.push(T[i].branchB())
            }
            T[i].completed = true
        }
    }

    for(let i = 0; i&amp;lt; T.length; i++){
        T[i].show(ctx)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function receives 8 parameters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;ctx&lt;/code&gt; Reference to the context of the canvas object &lt;code&gt;canvas.getContext('2d')&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;p1&lt;/code&gt; Object of type &lt;code&gt;Victor&lt;/code&gt; that contains the coordinates of the starting point of the trunk.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;p2&lt;/code&gt; Object of type &lt;code&gt;Victor&lt;/code&gt; that contains the coordinates of the point where the stem ends.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;al&lt;/code&gt; Angle of rotation (in radians) of the left branches.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ar&lt;/code&gt; Angle of rotation (in radians) of the right branches.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;divl&lt;/code&gt; Left Branch Growth Factor.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;divr&lt;/code&gt; Right branch growth factor.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;n&lt;/code&gt; Integer representing the number of levels.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It should be noted that the growth factor must be in the range of 0 to 1 for everything to make sense.&lt;/p&gt;

&lt;p&gt;This is how our fractal will look:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bayq01to--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cwyyap0ak033jf0i5pvt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bayq01to--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cwyyap0ak033jf0i5pvt.png" alt="Image description" width="427" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  L-System
&lt;/h2&gt;

&lt;p&gt;Finally, I will tell you about an algorithm that generalizes everything we have seen up to now, since with it you can obtain any possible fractal. The algorithm finds a great application when it comes to generating video game maps (both trees and terrain).&lt;/p&gt;

&lt;p&gt;An L-System consists of an alphabet with which character strings are generated following certain rules and starting with an initial &lt;code&gt;string&lt;/code&gt; called &lt;code&gt;axion&lt;/code&gt; Let's see an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;axion = "A"
rule1 = {key:"A", value:"AB"} //A =&amp;gt;&amp;gt; AB
rule2 = {key:"B", value:"C"} //B ==&amp;gt; C

//It generates
//1. A
//2. AB
//3. ABA
//4. ABAAB
//5. ABAABABA
//.......
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Given this, a small interpreter can be built if we define some rules, for example:&lt;/p&gt;

&lt;p&gt;If our string only contains the characters &lt;code&gt;F [ ] + -&lt;/code&gt;, we can define that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;F&lt;/code&gt; Draw a vertical line&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[&lt;/code&gt; Saves the reference of the last point of the drawn segment to a stack.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;]&lt;/code&gt; Pop point from the stack.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;+&lt;/code&gt; Rotate &lt;code&gt;n&lt;/code&gt; degrees clockwise the segment to draw.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-&lt;/code&gt; Rotate &lt;code&gt;n&lt;/code&gt; degrees counterclockwise the segment to draw.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With this defined all we have to do is correctly select the &lt;code&gt;axion&lt;/code&gt; rules and angles to generate any desired shape.&lt;/p&gt;

&lt;p&gt;For the programming we will create 3 functions, one that generates the pattern, another that interprets the generated pattern and the function that draws the figure.&lt;/p&gt;

&lt;p&gt;First we import the dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Victor from 'victor'
import {drawLine2Point} from './paint'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Function that generates the pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const create_pattern = (sentence, rules) =&amp;gt; {
    let nextSentece = ''
    for(let i = 0; i &amp;lt; sentence.length; i++){
        let current = sentence.charAt(i)
        let found = false
        for(let r = 0; r &amp;lt; rules.length; r++){
            if(current === rules[r].a){
                found = true
                nextSentece += rules[r].b
                break
            }
        } 
        if(!found)
            nextSentece += current
    }

    return nextSentece
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interpreter function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const interpreter = (ctx, sentence, a, b, angle) =&amp;gt; {
    let stack = []

    let l = {
        p1: a,
        p2: b
    }


    for(let i = 0; i &amp;lt; sentence.length; i++){
        let current = sentence.charAt(i)

        if(current === 'F'){
            drawLine2Point(ctx, l.p1, l.p2)
            let newp1 = l.p2
            let newp2 = new Victor(l.p2.x, l.p2.y).subtract(l.p1)
            newp2.add(l.p2)

            l = {
                p1: newp1,
                p2: newp2
            }
        }else if(current === '+'){
            let newp1 = l.p1
            let newp2 = new Victor(l.p2.x, l.p2.y).subtract(l.p1)
            newp2.rotate(angle)
            newp2.add(newp1)
            l = {
                p1: newp1,
                p2: newp2
            }
        }else if(current === '-'){
            let newp1 = l.p1
            let newp2 = new Victor(l.p2.x, l.p2.y).subtract(l.p1)
            newp2.rotate(-angle)
            newp2.add(newp1)
            l = {
                p1: newp1,
                p2: newp2
            }
        }else if(current === '['){
            stack.push(l)
        }else if(current === ']'){
            l = stack.pop()
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally the function that draws the fractal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const Lsystem = (ctx, axion, rules, a, b, angle, factor_scale, n) =&amp;gt; {
    let sentence = axion
    let scale = 1
    while(n--){
        sentence = create_pattern(sentence, rules)
        scale *= factor_scale
    }

    let dir = new Victor(b.x, b.y).subtract(a) 
    dir.divide(new Victor(scale, scale))
    dir.add(a)
    interpreter(ctx, sentence, a, dir, angle)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function receives 8 parameters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;ctx&lt;/code&gt; Reference to the context of the canvas object &lt;code&gt;canvas.getContext('2d')&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;axion&lt;/code&gt; &lt;code&gt;string&lt;/code&gt; representing the axiom.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rules&lt;/code&gt; Array containing all defined rules.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;a&lt;/code&gt; Object of type &lt;code&gt;Victor&lt;/code&gt; indicating the start of the segment.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;b&lt;/code&gt; Object of type &lt;code&gt;Victor&lt;/code&gt; indicating the end of the segment.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;angle&lt;/code&gt; Angle in radians indicating the rotation of the segment.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;factor_scale&lt;/code&gt; Value that allows to adjust the drawing as the levels grow.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;n&lt;/code&gt; Integer representing the number of levels.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here are some examples:&lt;/p&gt;

&lt;h3&gt;
  
  
  Tree
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CB1N3XbB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2wzbfrntb42j4owagqoy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CB1N3XbB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2wzbfrntb42j4owagqoy.png" alt="Image description" width="880" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Hibiscus a 30 grados
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hFGQUfYz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a5gc8mb3dkepv8cjxjsj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hFGQUfYz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a5gc8mb3dkepv8cjxjsj.png" alt="Image description" width="880" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Hilbert curve
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aLgYd9nB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9rxx73mmkd6m79f3g8p3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aLgYd9nB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9rxx73mmkd6m79f3g8p3.png" alt="Image description" width="880" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Triangle of Sierpinski
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FHcWWwCY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hn08gc9bjteedf221md9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FHcWWwCY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hn08gc9bjteedf221md9.png" alt="Image description" width="880" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
