mario::konrad
programming / C++ / sailing / nerd stuff
Julia Set
© 2013-03-21 / Mario Konrad

Die Julia Menge wird wie folgt berechnet:

zn+1=zn2+cz_{n+1}=z_n^2 + c mit z,cz,c in \mathbb{C}

Es wird ein bestimmtes cc gewählt, im Bereich c=22ic=-2-2i bis 2+2i2+2i

Der Startwert von zz entspricht dem laufenden Punkt auf dem zu zeichnenden Bild, ebenfalls im Bereich z=22iz=-2-2i bis 2+2i2+2i

Maximale Iterationen: 2020

Julia Menge bei -0.6 + 0.4i

Interaktiv

Im rechten Feld kann mit der Maus herumgefahren werden um den Wert für die Julia-Menge zu definieren. Das linke Bild zeigt die dazugehörige Julia-Menge.

HTML5 Code

var re_min = -2.0;
var re_max =  2.0;
var im_min = -2.0;
var im_max =  2.0;

var max_iter = 20;

function draw_canvas_julia_1(c_re, c_im)
{
    var canvas = document.getElementById("embed-julia-1");
    var context = canvas.getContext('2d');
    var output = context.createImageData(canvas.width, canvas.height);
    var data = output.data;

    for (var y = 0; y < output.height; ++y) {
        for (var x = 0; x < output.width; ++x) {
            var z_re = re_min + (re_max - re_min) / output.width * x;
            var z_im = im_min + (im_max - im_min) / output.height * y;
            var i = 0;
            for (; (i < max_iter) && (Math.sqrt(z_re * z_re + z_im * z_im) < 2.0); ++i) {
                z1_re = z_re * z_re - z_im * z_im + c_re;
                z1_im = 2.0 * z_re * z_im + c_im;
                z_re = z1_re;
                z_im = z1_im;
            }
            if (i >= max_iter) {
                data[(y*output.width + x)*4 + 0] = 0; // red
                data[(y*output.width + x)*4 + 1] = 0; // green
                data[(y*output.width + x)*4 + 2] = 0; // blue
                data[(y*output.width + x)*4 + 3] = 255; // alpha
            } else {
                data[(y*output.width + x)*4 + 0] = (255 * i) / max_iter; // red
                data[(y*output.width + x)*4 + 1] = (255 * i) / max_iter; // green
                data[(y*output.width + x)*4 + 2] = (255 * i) / max_iter; // blue
                data[(y*output.width + x)*4 + 3] = 255; // alpha
            }
        }
    }

    context.putImageData(output, 0, 0);
}

function draw_canvas_julia_2(c_re, c_im)
{
    var canvas = document.getElementById("embed-julia-2");
    var context = canvas.getContext('2d');
    var output = context.createImageData(canvas.width, canvas.height);
    var data = output.data;

    for (var y = 0; y < output.height; ++y) {
        for (var x = 0; x < output.width; ++x) {
            var z_re = re_min + (re_max - re_min) / output.width * x;
            var z_im = im_min + (im_max - im_min) / output.height * y;
            var i = 0;
            for (; (i < max_iter) && (Math.sqrt(z_re * z_re + z_im * z_im) < 2.0); ++i) {
                z1_re = z_re * z_re - z_im * z_im + c_re;
                z1_im = 2.0 * z_re * z_im + c_im;
                z_re = z1_re;
                z_im = z1_im;
            }
            if (i >= max_iter) {
                data[(y*output.width + x)*4 + 0] = 0; // red
                data[(y*output.width + x)*4 + 1] = 0; // green
                data[(y*output.width + x)*4 + 2] = 0; // blue
                data[(y*output.width + x)*4 + 3] = 255; // alpha
            } else {
                data[(y*output.width + x)*4 + 0] = (255 * i) / max_iter; // red
                data[(y*output.width + x)*4 + 1] = (255 * i) / max_iter; // green
                data[(y*output.width + x)*4 + 2] = (255 * i) / max_iter; // blue
                data[(y*output.width + x)*4 + 3] = 255; // alpha
            }
        }
    }

    context.putImageData(output, 0, 0);
}

function draw_canvas_mouse()
{
    var canvas = document.getElementById('embed-mouse');
    var context = canvas.getContext('2d');

    context.beginPath();
    context.arc(canvas.width / 2, canvas.height / 2, canvas.width / 2, 0, 2 * Math.PI, false);

    context.moveTo(0, canvas.height / 2);
    context.lineTo(canvas.width, canvas.height / 2);

    context.moveTo(canvas.width / 2, 0);
    context.lineTo(canvas.width / 2, canvas.height);

    context.stroke();
}

function getMousePos(canvas, evt)
{
    // get canvas position
    var obj = canvas;
    var top = 0;
    var left = 0;
    while (obj && obj.tagName != 'BODY') {
        top += obj.offsetTop;
        left += obj.offsetLeft;
        obj = obj.offsetParent;
    }

    // return relative mouse position
    var mouseX = evt.clientX - left + window.pageXOffset;
    var mouseY = evt.clientY - top + window.pageYOffset;
    return {
        x: mouseX,
        y: mouseY
    };
}

window.onload = function()
{
    draw_canvas_julia_1(-0.6, 0.4);
    draw_canvas_mouse();

    var canvas = document.getElementById('embed-mouse');
    var context = canvas.getContext('2d');

    canvas.addEventListener('mousemove',
        function(evt) {
            var pos = getMousePos(canvas, evt);
            var c_re = re_min + (re_max - re_min) * pos.x / canvas.width;
            var c_im = im_min + (im_max - im_min) * pos.y / canvas.height;
            draw_canvas_julia_2(c_re, c_im);
            },
        false);
    draw_canvas_mouse();
}