分形解释

5

最近我对分形、背后的数学和它们能产生的视觉效果很感兴趣。

但我真的不知道如何将数学公式映射到绘制图片的代码中。
给定曼德博集合的这个公式:Pc(z) = z * z + c
它与以下代码有何区别:

$outer_adder = ($MaxIm - $MinIm) / $Lines;
$inner_adder = ($MaxRe - $MinRe) / $Cols;
for($Im = $MinIm; $Im <= $MaxIm; $Im += $outer_adder)
{
  $x=0;
  for($Re = $MinRe; $Re <= $MaxRe; $Re += $inner_adder)
  {
    $zr = $Re;
    $zi = $Im;
    for($n = 0; $n < $MaxIter; ++$n)
    {
      $a = $zr * $zr;
      $b = $zi * $zi;
      if($a + $b > 2) break;
      $zi = 2 * $zr * $zi + $Im;
      $zr = $a - $b + $Re;
    }
    $n = ($n >= $MaxIter ? $MaxIter - 1 : $n);
    ImageFilledRectangle($img, $x, $y, $x, $y, $c[$n]);
    ++$x;
  }
  ++$y;
}

代码并不完整,仅展示了主要迭代部分以简洁为目的。

所以问题是:有人能解释一下数学与代码的比较吗?

编辑:明确一下,我找到了很多关于数学的资源和很多展示代码的资源,但是没有地方可以找到两者结合的好解释。

1个回答

18

免责声明。在此之前我对分形一无所知,但一直想了解,于是我阅读了维基百科文章并决定在这里写下我所发现的内容。 正如人们所说,如果你想理解某个东西,试着向别人解释它。;)

好的,我们将要对复数进行操作。实际上,复数是一对(实)数字,因此,对于我们的php程序员来说,它是一个两个元素的数组。

    /// Construct a complex number from two reals
    function cpl($re, $im) {
        return array($re, $im);
    }

现在我们需要告诉 PHP 如何对我们的复数进行算术运算。我们需要加法、乘法和模("norm")运算符。(有关更多详细信息,请参见http://mathworld.wolfram.com/topics/ComplexNumbers.html)。
    /// Add two complex numbers.
    function cadd($p, $q) {
        return cpl(
            $p[0] + $q[0],
            $p[1] + $q[1]);
    }

    /// Multiply two complex numbers.
    function cmul($p, $q) {
        return cpl(
            $p[0] * $q[0] - $p[1] * $q[1],
            $p[0] * $q[1] + $p[1] * $q[0]);
    }

    /// Return the norm of the complex number.
    function cmod($p) {
        return sqrt($p[0] * $p[0] + $p[1] * $p[1]);
    }

现在我们编写一个函数,如果给定(复杂)点$c$属于Mandelbrot集,则返回true。
如果所有点$z=z^2+c$都在半径为2的圆内,则点$c$属于该集合。
  • 我们从复数$z=(0,0)$开始。
  • 在每个步骤中,我们计算$z=z*z+c$。
  • 如果$|z|$ > 2,也就是说,我们超出了圆形区域,那么该点不在集合中。
  • 否则重复上述步骤。
为了防止无限循环,限制最大迭代次数。
    function is_in_mandelbrot_set($c, $iterations) {
        $z = cpl(0, 0);
        do {
            if(cmod($z) >= 2)
                return false;
            $z = cadd(cmul($z, $z), $c);
        } while($iterations--);
        return true;
    }

其余部分与数学无关,非常明显。

    function mandelbrot($img, $w, $h) {
        $color = imagecolorallocate($img, 0xFF, 0, 0);
        $zoom = 50;
        $iters = 30;

        for($x = 0; $x < $w; $x++) {
            for($y = 0; $y < $h; $y++) {

                // scale our integer points 
                // to be small real numbers around 0

                $px = ($x - $w / 2) / $zoom;
                $py = ($y - $h / 2) / $zoom;

                $c = cpl($px, $py);

                if(is_in_mandelbrot_set($c, $iters))
                    imagesetpixel($img, $x, $y, $color);
            }
        }

        return $img;
    }

    $w = 200;
    $h = 200;

    header("Content-type: image/png");
    imagepng(
        mandelbrot(
            imagecreatetruecolor($w, $h), $w, $h));

结果

alt text

当然,这段代码极其无效。它的唯一目的是理解数学概念。

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