分形解释

时间:2010-09-16 09:56:32

标签: php fractals mandelbrot

一段时间以来,我一直对分形,背后的数学以及它们可以产生的视觉效果感兴趣。

我真的无法弄清楚如何将数学公式映射到绘制图片的代码片段 鉴于mandelbrot集的这个公式: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 个答案:

答案 0 :(得分:18)

声明。我以前对分形一无所知,但总是想知道,所以我读过wikipedia article并决定写下我在这里找到的东西。 正如他们所说,如果您想了解某些内容,请尝试向其他人解释。 ;)

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

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

现在我们需要告诉php如何在复杂数字上进行算术运算。我们需要加法,乘法和mod(“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

如果所有点c都位于半径为2的圆内,则点z = z^2 + c属于该集。

  • 我们从复数z =(0,0)开始。
  • 在每一步中,我们计算z = z * z + c。
  • 如果modulus of z&gt; 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

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