문제

I'm messing around with some Mandlebrot set stuff because I think the pictures it produces are pretty. I thought I might try to tackle the problem of drawing one in javascript to see what I could do. I looked at a couple algorithms, namely:

http://library.thinkquest.org/26242/full/progs/a2.html

Which I translated into this:

drawGraph: function(canvas,resolution,iterations,colors,coefficent){

                var context = canvas.getContext('2d');

                for(var m = 0; m < resolution.x; m++){
                    for(var n = 0; n < resolution.y; n++){
                        var x = m, 
                            x2 = x*x,
                            y = n, 
                            y2 = y*y;

                        var i;
                        for(i = 1; i < iterations; i++){
                            if(x2 + y2 > 4) break;

                            var new_x = x2 - y2 + coefficent.a;
                            var new_y = 2*x*y + coefficent.b;

                            x = new_x;
                            y = new_y;
                        }

                        var color = i % colors;

                        DrawUtils.drawPoint(context,m,n,color); 
                    }
                }
            }

Which essentially draws a box of one color.

Then I tried this one:

http://en.wikipedia.org/wiki/Mandelbrot_set#Escape_time_algorithm

Which I translated into this:

drawGraph: function(canvas,resolution,iterations,colors,coefficent){

                var context = canvas.getContext('2d');

                for(var m = 0; m < resolution.x; m++){
                    for(var n = 0; n < resolution.y; n++){
                        var x = 0,
                            y = 0,
                            x0 = ((m/resolution.x) * 3.5) - 2.5,
                            y0 = ((n/resolution.y) * 2) - 1;

                        var i = 0;
                        while(x*x + y*y < 4 && i < iterations){
                            var x_temp = x*x - y*y + x0;
                            y = 2*x*y + y0;
                            x  = x_temp;
                            i++;
                        }

                        var color = 0;
                        if(x*x + y*y >= 4){
                            color = i % colors;
                        }

                        DrawUtils.drawPoint(context,m,n,color);
                    }
                }
            }

Which produces a black box. The wording in the algorithm kind of confused me though since it said x0 and y0 scaled are factors of the pixel, but then after the algorithm, it says the coefficient c = x0 + iy0; so, does that mean I don't pass a predetermined coefficient into the function?

For most of these tests I was using the coefficient 0.25 + 0i, but I tried others that produced the exact same results.

What am I doing wrong here?

도움이 되었습니까?

해결책

First point: you need to be clear about the difference between Julia sets and the Mandelbrot set. Both are insights into the behaviour of f(z) = z^2 + c under iteration, but from different perspectives.

For a Julia set, we fix c and make a plot of how different initial zs behave

For the Mandelbrot set, we make a plot of how the same initial z = 0 behaves for different cs.

With that addressed...


For your first code (which tries to draw the a Julia set for the c in coefficient), your translation from the BASIC in the first page you link to is not quite right. Where that has

‘ run through every point on the screen, setting 
‘ m and n to the coordinates
FOR m = x_minimum TO x_maximum STEP x_resolution
             FOR n = y_minimum TO y_maximum STEP y_resolution
                          ‘ the initial z value is the current pixel,  
                          ‘ so x and y have to be set to m and n
                          x = m: y = n

you have

        for(var m = 0; m < resolution.x; m++){
            for(var n = 0; n < resolution.y; n++){

which is close, except for the crucial point that you are not taking any steps to implement STEP x_resolution. Your m is an integer that runs from 0 to resolution.x - 1 in steps of 1; and your x is set to m.

So instead of looking at the complex plane from say -2-2i to 2+2i (a decent viewport for seeing a Julia set), you are instead looking at the complex plane from 0 to resolution.x + resolution.y i, which will have at most a few pixels set in its lower-left corner.


The second code (which attempts to draw a Mandelbrot set) does have code to scale to a correct range, and I can't immediately see what's going wrong - I would debug and see if m/resolution.x is always 0, as @user973572 suggests may be the problem.

다른 팁

In your first example, I think you forgot to update x2 and y2 so they are always the same value. You need to update x2 and y2 before checking if the sum is greater than 4. Something like

for(i = 1; i < iterations; i++){
    x2 = x*x,
    y2 = y*y
    if(x2 + y2 > 4) break;

which is probably wrong because I know nothing about javascript.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top