4

所以我阅读了这篇文章: 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中进行逻辑运算。

下面是它的样子: [已删除]
如果您删除 url 末尾的 2,您会看到另一个版本,我只是重写了一些 c++ 代码片段。但是缩放有点奇怪,这就是为什么我想自己写。

我了解 mandelbrot 集创建的基本概念,但正如我所说,复杂的部分让我感到困扰。那里可能有更简单的解释吗?

4

1 回答 1

16

你首先要明白这一点:

z = z^2 + c

让我们分解一下。

z和都是c复数(最近的一个问题告诉我要强调这一点,它们小数,看起来像这样:)c=-0.70176-0.3842i。复数可以有一个“非实数”的部分,正确的术语是虚数部分,你可以用以下形式写一个复数

(a + bi)这与以下内容相同:(a + b*i)

如果 b 为 0,那么你有一个 a a + 0i,它a没有部,你有一个实数。

您的链接没有提到复数的最重要属性,尤其是其部的属性i == sqrt(-1)。在实数领域,没有负数的平方根之类的东西,这就是复数的用武之地,它允许您获得 -1 的平方根。让我们提高i到 2: 的幂i^2 == -1,魔法!

虚部 ( i) 必须由您处理(特殊平方),或者您使用的编程语言将提供一个 Complex 类型来为您处理它。

现在回到扩展z^2

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

让我们也分解一下:

  • a^2=> 这很简单,它是一个实数
  • bi^2=> 棘手的部分。这是真的b^2*i^2。我们得到了一个i^2,它是-1,这使得它b^2*-1或 : -b^2。所以这也是一个数。
  • 2*a*b*i=> 这将是

结果: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 集,取自维基百科

通常的工作流程是这样的:

  • 在复平面上选择一个点,例如 (1.01312 + 0.8324i) => 这将是c!
  • 在第一次迭代之前,将 (0, 0i) 放入zthen 中迭代多次,如前所述 => z = z^2 + c。是的,您正在对一个点进行平方并添加相同的点,这是Mandelbrot 集的一个非常重要的属性。对于初学者来说,这样做 50 次。这将为您提供一个复数作为结果。
  • 如果得到的复数(实数或虚数)的任何部分等于或大于 2,则我们假设该点将趋于无穷大,并且我们认为该点不是Mandelbrot 集的一部分*。当您需要为点着色时就是这种情况(这是 Mandelbrot 集的彩色部分)。如果复数的两个部分都小于 2,我们假设该点永远不会达到无穷大(即使迭代了无数次),并将该点视为 Mandelbrot 集的一部分,其颜色将为黑色。
  • 重复(选择下一个点,将其值放入c,将零放入z并计算)

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

于 2012-03-30T11:15:09.173 回答