JavaScript中的朱利亚集合

3
我正在尝试制作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

首先,你需要明确朱利亚集与曼德博集之间的区别。它们都是对f(z)=z²+c在迭代下行为的洞察,但是从不同的角度来看。

对于一个朱利亚集,我们固定c,然后绘制不同初始z的行为图。

对于曼德博集,我们绘制同一个初始值z=0在不同的c下的行为图。

说完这些……


针对你的第一段代码(试图绘制coefficient中的c的一个朱利亚集),你从第一页链接的BASIC代码转换的不太正确。那里面有:

‘ 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++){
除了一个关键点,你没有采取任何步骤来实现STEP x_resolution,这使得它很接近。你的m是一个整数,从0resolution.x - 11的步长运行;而你的x设置为m
因此,你不是从例如-2-2i2+2i(查看Julia集合的良好视口)来查看复平面,而是从0resolution.x + resolution.y i来查看复平面,其在其左下角最多只有几个像素被设置。
第二段代码(试图绘制曼德博集合)确实有正确缩放范围的代码,我无法立即看出问题在哪里——我会进行调试,并查看m/resolution.x是否始终为0,就像@user973572所建议的那样。

天啊,我的Julia集合终于成功了!我按照你说的范围缩小了x和y,并确保在每次迭代之前重置x * x和y * y,然后才退出。现在我只需要想出一种自动产生颜色的好方法......如果我硬编码颜色值,那么使用模运算似乎只能起到一定作用。 - kand
所以,我尝试了维基百科页面http://en.wikipedia.org/wiki/Julia_set#Quadratic_polynomials中显示的一些c值:但它们最终在形状的“外部”具有正确的形状,但是形状的“内部”全部填充了奇怪的线条。这是一个例子:http://imgur.com/ynrCI - kand
结果发现这实际上是我的着色技术的问题...我得想出更好的方法来产生颜色。 - kand

2

在你的第一个例子中,我认为你忘记更新x2和y2,所以它们始终是相同的值。在检查总和是否大于4之前,你需要更新x2和y2。类似这样:

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

这可能是错误的,因为我对Javascript一无所知。


好的,我也尝试过了,但仍然出现了黑色方框。它似乎总是过早地跳出循环,导致每个像素的颜色都为1。这对我来说是有道理的,因为xx + yy很快就会大于4,但我查看的所有算法似乎都有相同的逻辑... - kand
对于曼德博集合,由于整数运算,(m/resolution.x)是否返回0?如果是这样,那可能会有问题。我已经在Tcl中完成了曼德博集合,如果需要,我可以在这里粘贴一些代码。 - user973572

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接