views:

73

answers:

1
+1  Q: 

Fractals explained

For a while now I've been interested in fractals, the math behind them and the visuals they can produce.

I just can't really figure out how to map the mathematical formula to a piece of code that draws the picture.
Given this formula for the mandelbrot set: Pc(z) = z * z + c
How does that compare to the following code:

$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;
}

Code is not complete, just showing the main iteration part for brevity.

So the question is: could someone explain to me how the math compares to the code?

Edit: To be clear, I've found dozens of resources explaining the math, and dozens of resources showing code, but nowhere can I find a good explanation of the two combined.

+2  A: 

Disclaimer. I didn't know anything about fractals before, but always wanted to know, so I've read the wikipedia article and decided to write what I've found here. As they say, if you want to understand something, try explaining it to someone else. ;)

Okay, we're going to operate on complex numbers. A complex number is actually a pair of (real) numbers, so, for us php programmers, let it be a two-elements array.

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

Now we need to tell php how to do arithmetics on our complex numbers. We'll need addition, multiplication and the mod ("norm") operator. (see http://mathworld.wolfram.com/topics/ComplexNumbers.html for more details).

    /// 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]);
    }

Now we write a function that returns true if the given (complex) point $c belongs to the mandelbrot set

A point c belongs to the set if all points z = z^2 + c lie inside the circle with the radius 2.

  • We start with the complex number z = (0, 0).
  • On each step we calculate z = z * z + c.
  • If modulus of z > 2 - that is, we're out of the circle - the point is NOT in set
  • Otherwise repeat the step.

To prevent that from looping endlessly, limit the max number of iterations.

    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;
    }

The rest has nothing to do with math and is quite obvious

    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));

Result

alt text

Of course, this code is ineffective to the extreme. Its only purpose is to understand the math concept.

stereofrog
Wow, thanks for this great answer! I'll get back to it tonight when I have more time to actually try and comprehend what you have just written :)
Dennis Haarbrink