无法计算mandelbrot集迭代

时间:2012-02-12 22:11:21

标签: javascript fractals mandelbrot

所以我读了这篇文章:http://www.wikihow.com/Plot-the-Mandelbrot-Set-By-Hand 但是我坚持第7步。我在javascript画布中绘制了这个集合。

我想要的只是基本的C值。

for (var y = 0; y < ImageHeight; y++) {
    for (var x = 0; x < ImageWidth; x++) {

        // Pixel-Position for ImageObject
        var xy = (x + y * image.width) * 4;

        // Convert Image-Dimension to a radius of 2
        var xi = ((x / ImageWidth) * 4) - 2;
        var yi = ((y / ImageHeight) * 4) - 2;

        for (var n = 0; n < MaxIterations; n++) {

            // Complex number stuff..?
            z = (xi*xi) + (yi*yi) + c;
            c = 0; // Somethig with z ..?

            if (z < 4) {

                image.data[xy] = inner_color[0];
                image.data[xy+1] = inner_color[1];
                image.data[xy+2] = inner_color[2];
                image.data[xy+3] = Math.round(n * cdiff);

            } else {

                image.data[xy] = outer_color[0];
                image.data[xy+1] = outer_color[1];
                image.data[xy+2] = outer_color[2];
                image.data[xy+3] = Math.round(n * cdiff);

                break;
            }
        }
    }
}

我还读了很多关于虚数和东西的内容,但我不太明白如何用它们来计算。它们对我来说似乎毫无用处,因为你不得不将它们转换回实数,以便在javascript中进行逻辑运算。

这是它的样子:[删除]
如果你删除网址末尾的2,你会看到另一个版本,我只是重写了一个小的c ++ snippit。 但缩放有点奇怪,这就是为什么我要自己写这一切......

我理解mandelbrot集创作的基本概念,但正如我所说,复杂的部分让我很烦恼。那里可能有更简单的解释吗?

1 个答案:

答案 0 :(得分:15)

你必须首先理解这一点:

z = z^2 + c

让我们把它分解。

zc都是复数(最近的一个问题让我强调这一点,他们小数位数,看起来像这样:{{1 }})。复数可以有一个“不真实”的部分,正确的术语是虚构的部分,你可以用以下形式写一个单个复数:

c=-0.70176-0.3842i(a + bi)

相同

如果b为0,那么您的(a + b*i)就是a + 0i,因此如果没有虚构部分,您就会得到一个实数。

您的链接未提及复数的最重要属性,尤其是{em>虚构部分a的属性。在实数字段中,没有负数的平方根,这就是复数进入的地方,允许你的平方根为-1。让我们将i == sqrt(-1)提升为2的力量:i,魔法!

虚部(i^2 == -1)必须由你(特殊方格)处理,或者你使用的编程语言将提供一个复杂类型,为你处理它。

现在回到展开i

z^2,因此z == (a+bi) z^2 == (a+bi)^2

让我们打破这个:

  • z^2 == (a^2 + bi^2 + 2*a*bi) =&gt;这很简单,它是一个实数
  • a^2 =&gt;棘手的部分。这真的是bi^2。我们来到b^2*i^2 i^2-1b^2*-1或:-b^2。所以这也是一个真正的号码。
  • 2*a*b*i =&gt;这将是虚构的部分

结果:z^2 = (a^2-b^2+2*a*bi)

示例(有点过于详细。您可以将其视为循环中的第一次迭代):

z = (5 + 3i)
z^2 = (5 + 3i)^2
    = (5^2 + 3^2*i^2 + 2*5*3i)
    = (25 + 9i^2 + 30i)
    = (25 + 9*-1 + 30i)
    = (25 - 9 + 30i)
    = (16 + 30i)

现在,如果您理解复数的迭代和乘法,Mandelbrot上的一些单词(以及c值):

当你想要创建一个Mandelbrot集时,你真的在​​寻找复平面上的点,如果迭代超过 - 比如说50次 - 那么上面讨论的迭代就永远不会变为无穷大。 Mandelbrot集是通常看到的“Mandelbrot”图片中的黑色部分,而不是闪亮的彩色部分。

Mandelbort set, taken from Wikipedia

通常的工作流程如下:

  • 选择复平面上的一个点,比方说(1.01312 + 0.8324i)=&gt;这将是c
  • 的价值
  • 在第一次迭代之前将(0,0i)放入z然后迭代多次,如前所述=&gt; z = z^2 + c。是的,你正在为一个点加注并添加相同的点,这是 Mandelbrot集的一个非常重要的属性。对于起动器这样做50次。这将为您提供一个复杂的数字。
  • 如果得到的复数的任何部分(Real或Imaginary)等于或大于2,那么我们假设这一点会变为无穷大,我们认为这一点不是 Mandelbrot集*的一部分*。当您需要为点着色时(这是Mandelbrot集的彩色部分)就是这种情况。如果复数的两个部分都小于2,我们假设该点永远不会变为无穷大(即使迭代次数超过数十亿次),并将此点视为Mandelbrot集的一部分,其颜色将为黑色。
  • 重复(选择下一个点,将其值放入c,将零置于z并计算)

*实际上,验证点是否是集合的一部分有点复杂,但这适用于原型