Julia set, Cantor set and Fern fractal implemented in JavScript

In the previous post, I presented a simple fractal - bifurcation diagram of the logistic map. Today I will show more fractals and their implementation in JavaScript, they are embedded below so it's possible to run them on this page.

Julia set

The equitation for Julia set is given for complex numbers:

fc(x) = x2 + c

This implementation uses random numbers to create the fractal.

Click to draw Julia set. This can take a while.

function drawJuliaFractal(canvasID)
{
    // get canvas to be able to draw into it
    var canvas = document.getElementById(canvasID)
    var ctx = canvas.getContext("2d")

    var width = canvas.width
    var height = canvas.height

    var c_r = -0.73
    var c_i = 0.19
    var step = 0.002

    // z= a+bi
    for(var a = -2; a < 2; a+=step)
    {
        for(var b = -2; b < 2; b+=step)
        {
            var za = a
            var zb = b
            for(var n = 0; n < 160; n++){
               var za_temp = (za * za) - (zb * zb)
               zb = 2 * za *zb
               za = za_temp

               // add c constant
               za+=c_r
               zb+=c_i
            }

            if(Math.sqrt((za * za) + (zb * zb)) < 2)
            {
                var zoom = width / 3
                var x_print = (zoom * a) + (width / 2)
                var y_print = (zoom * b) + (height / 2)
                putPixel(ctx, x_print, y_print)
            }

        }
    }
}

Fern fractal

Unfortunately, I don't remember the direct mathematics formula.

This implementation uses random numbers to create the fractal.

Click to draw Fern fractal.

function drawFernFractal(canvasID)
{
    // get canvas to be able to draw into it
    var canvas = document.getElementById(canvasID)
    var ctx = canvas.getContext("2d")

    var width = canvas.width
    var height = canvas.height

    var max_step = 20000
    var x = 0
    var y = 0

    for(var i=0; i<max_step; i++)
    {
        var r = Math.random()

        if(r <= 0.01)
        {
            x = 0
            y = 0.16 * y
        }
        else if(r <= 0.08)
        {
            x = (0.2 * x) - (0.26 * y)
            y = 0.23*x+0.22*y+1.6
        }
        else if(r <= 0.15)
        {
            x = (-0.15 * x) + (0.28 * y)
            y = (0.26 * x) + (0.24 * y) + 0.44
        }
        else 
        {
            x = (0.85 * x) + (0.04 * y)
            y = (-0.04 * x) + (0.85 * y) + 1.6
        }


        // scale fractal to best fit to the canvas object
        var zoom = width / 10
        x_print = width - ((x * zoom) + (width / 2))
        y_print = height - (y * zoom)

        putPixel(ctx, x_print, y_print)
    }
}

Cantor set

The equitation for Cantor set is given by formula:

Cn = Cn-1/3 ∪ (2/3 + Cn-1/3), C0 = [0,1]

This implementation uses recursion to create the fractal.

Click to draw Cantor set.

// Note, initial invocation should be with xb = canvas width
function drawCantor(canvasID, level, xa, xb)
{
    // get canvas to be able to draw into it
    var canvas = document.getElementById(canvasID)
    var ctx = canvas.getContext("2d")

    var width = canvas.width
    var height = canvas.height

    var level_max = 10;
    if(level < level_max)
    {
        // put bar
        var bar_height = 3
        for(var i = xa; i < xb; i++)
        {
            var h = level * 6

            for(var j = h; j != (h + bar_height); j++)
            {
                var y_print = j +( height / 2)
                putPixel(ctx, i, y_print)
            }
        }

        //  call itself to print two child bars
        drawCantor(canvasID, level+1, xa, xa+ (xb-xa)/3)
        drawCantor(canvasID, level+1, xb - (xb-xa)/3, xb)
    }
}

To check exactly, how the scripts are working please take a look on the source code of this page.

Above scripts were created a couple of years ago, they may not be aligned with the modern way of doing things in JavaScript.

3 comments:

  1. Cantor set should go from the middle of the image till infinitivy down.

    Sorry for redundant posts :)

    ReplyDelete
    Replies
    1. Yes, it's a limitation of the recursive algorithm - we have to stop it at some point.

      Delete