Джулия Сет В Джаваскрипте - PullRequest
       22

Джулия Сет В Джаваскрипте

3 голосов
/ 18 октября 2011

Я бездельничаю с некоторыми наборами Mandlebrot, потому что я думаю, что изображения, которые это производит, симпатичны. Я подумал, что мог бы попытаться решить проблему рисования в javascript, чтобы увидеть, что я могу сделать. Я посмотрел на пару алгоритмов, а именно:

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

Который я перевел на это:

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); 
                    }
                }
            }

Который по существу рисует прямоугольник одного цвета.

Тогда я попробовал это:

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

Который я перевел на это:

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);
                    }
                }
            }

Который производит черный ящик. Формулировка в алгоритме как-то меня смутила, поскольку в нем сказано, что масштабированные x0 и y0 являются факторами пикселя, но затем, после алгоритма, он говорит, что коэффициент c = x0 + iy0; итак, значит ли это, что я не передаю заранее заданный коэффициент в функцию?

Для большинства этих тестов я использовал коэффициент 0,25 + 0i, но я пробовал другие, которые давали точно такие же результаты.

Что я здесь не так делаю?

Ответы [ 2 ]

4 голосов
/ 19 октября 2011

Первое замечание: вам нужно четко понимать разницу между множествами Джулии и множеством Мандельброта. И то, и другое показывает поведение f(z) = z^2 + c при итерации, но с разных точек зрения.

Для набора Джулия мы фиксируем c и строим график того, как различные начальные z ведут себя

Для набора Мандельброта мы строим график того, как один и тот же начальный z = 0 ведет себя для разных c с.

С этим обратился ...


Для вашего первого кода (который пытается нарисовать набор Джулии для c в coefficient) ваш перевод с Бейсика на первой странице, на которую вы ссылаетесь, не совсем верен. Где это имеет

‘ 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

у вас есть

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

, что близко, за исключением того критического момента, что вы не предпринимаете никаких шагов для реализации STEP x_resolution. Ваш m - это целое число , которое выполняется с 0 до resolution.x - 1 с шагом 1; и ваш x установлен на m.

Таким образом, вместо того, чтобы смотреть на сложную плоскость от, скажем, -2-2i до 2+2i (приличное окно просмотра для просмотра набора Джулии), вы вместо этого смотрите на сложную плоскость от 0 до resolution.x + resolution.y i, которая в нижнем левом углу должно быть не более нескольких пикселей.


Второй код (который пытается нарисовать множество Мандельброта) имеет код для масштабирования до правильного диапазона, и я не могу сразу увидеть, что происходит не так - я бы отладил и посмотрел, если m/resolution.x всегда 0, как предполагает @ user973572, может быть проблема.

2 голосов
/ 18 октября 2011

В вашем первом примере, я думаю, вы забыли обновить x2 и y2, чтобы они всегда имели одинаковое значение. Вам нужно обновить x2 и y2 перед проверкой, если сумма больше 4. Что-то вроде

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

, что, вероятно, неправильно, потому что я ничего не знаю о javascript.

...