Search code examples
javascriptcanvaspseudocodefractalsmandelbrot

Mandelbrot set defined by a specific function


I'm experimenting with canvas and I'm trying to modify this piece of code, but unfortunately I don't understand some parts of it.

My question is - how to customize the above code to be defined for example by

f(z) = c^e(-z) 

(the formula is taken from a book with fractal examples)?

I know that I need to change this part of code:

function computeRow(task) {
    var iter = 0;
    var c_i = task.i;
    var max_iter = task.max_iter;
    var escape = task.escape * task.escape;
    task.values = [];
    for (var i = 0; i < task.width; i++) {
        var c_r = task.r_min + (task.r_max - task.r_min) * i / task.width;
        var z_r = 0, z_i = 0;

        for (iter = 0; z_r*z_r + z_i*z_i < escape && iter < max_iter; iter++) {
            // z -> z^2 + c
            var tmp = z_r*z_r - z_i*z_i + c_r;
            z_i = 2 * z_r * z_i + c_i;
            z_r = tmp;
        }
        if (iter == max_iter) {
            iter = -1;
        }
        task.values.push(iter);
    }
    return task;
}

But can't what z_i, z_r, c_i, c_r really means and how I could bind them to the above formula.

Any help would be greatly appreciated.


Solution

  • Complex number have a two part: real, imaginary.
    So z = a + b*i, where a is real part, and b*i is imaginary.
    In provided sample for z=z^2+c, where z=z_r+z_i*i

    NOTE: i*i = -1
    So z^2 = (z_r+z_i*i)*(z_r+z_i*i) = z_r*z_r+2*z_r*z_i*i + z_i*i*z_i*i = z_r*z_r+2*z_r*z_i*i - z_i*z_i
    now add c: z_r*z_r+2*z_r*z_i*i - z_i*z_i + c_r + c_i*i group it

    z_r*z_r+2*z_r*z_i*i - z_i*z_i + c_r + c_i*i = (z_r*z_r - z_i*z_i + c_r) + (2*z_r*z_i + c_i)*i
    

    So we get tmp var from code - is real part of new z

    tmp = z_r*z_r - z_i*z_i + c_r
    

    and imaginary part

    2*z_r*z_i + c_i
    

    Since z = z_r + z_i * i, we need assign

    z_r = z_r*z_r - z_i*z_i + c_r
    z_i = 2*z_r*z_i + c_i
    

    UPDATE: for f(z) = e^z - c

    first, few complex form: x = a+b*i = |x|(cos(p)+i*sin(p)) = |x|*e^(i*p)
    where |x| = sqrt(a*a + b*b) and p = b/a

    in our case: p=z_i/z_r, |z| = sqrt(z_r*z_r+z_i*z_i)

    e^z = e^(z_r+z_i*i) = e^z_r * (e^z_i*i) = e^z_r * (cos(p)+i*sin(p)) = (e^z_r * cos(p)) + i * (e^z_r * sin(p))
    

    subtract c:

    (e^z_r * cos(p)) + i * (e^z_r * sin(p)) - c_r - c_i*i = (e^z_r * cos(p) - c_r) + i * (e^z_r * sin(p) - c_i)
    

    so new z

    z_r = (e^z_r * cos(p) - c_r) = (e^z_r * cos(z_i/z_r) - c_r)
    z_i = (e^z_r * sin(p) - c_i) = (e^z_r * sin(z_i/z_r) - c_i)