phpmathmandelbrot

Mandelbrot set won't render correctly


I am currently trying to make an animated Mandelbrot set visualisation. But right now it won't even render a single frame correctly.

I don't know where I made the mistake. I guess there is an error in the math.Will you please have a look at it?

Here is a how it looks right now: Current state

Here is my mandelbrot function:

function mandelbrot($a, $b, $limit) {
  $a_orig = $a;
  $b_orig = $b;
  $count = 0;

  while(($count < $limit) && (sqrt(($a * $a) + ($b * $b)) <= 2)) {
    $a = ($a * $a) - ($b * $b) + $a_orig;
    $b = (2 * $a * $b) + $b_orig;

    $count++;
  }

  return $count;
}

And here is the entire code:

<?php

function HSVtoRGB(array $hsv) {
    list($H,$S,$V) = $hsv;
    //1
    $H *= 6;
    //2
    $I = floor($H);
    $F = $H - $I;
    //3
    $M = $V * (1 - $S);
    $N = $V * (1 - $S * $F);
    $K = $V * (1 - $S * (1 - $F));
    //4
    switch ($I) {
        case 0:
            list($R,$G,$B) = array($V,$K,$M);
            break;
        case 1:
            list($R,$G,$B) = array($N,$V,$M);
            break;
        case 2:
            list($R,$G,$B) = array($M,$V,$K);
            break;
        case 3:
            list($R,$G,$B) = array($M,$N,$V);
            break;
        case 4:
            list($R,$G,$B) = array($K,$M,$V);
            break;
        case 5:
        case 6: //for when $H=1 is given
            list($R,$G,$B) = array($V,$M,$N);
            break;
    }
    return array($R, $G, $B);
}

function mandelbrot($a, $b, $limit) {
  $a_orig = $a;
  $b_orig = $b;
  $count = 0;

  while(($count < $limit) && (sqrt(($a * $a) + ($b * $b)) <= 2)) {
    $a = ($a * $a) - ($b * $b) + $a_orig;
    $b = (2 * $a * $b) + $b_orig;

    $count++;
  }

  return $count;
}

ini_set("max_execution_time", 0);

header ("Content-Type: image/gif");

$num_frames = 60;
$size = 1024;
$points = array($size);

$image = imagecreate($size, $size);

for($j = 0; $j <= $num_frames; $j++) {
  $tmp_color = HSVtoRGB(array(($j + 1) / ($num_frames + 1), 1, 1));
  $color[$j] = imagecolorallocate($image, $tmp_color[0] * 255, $tmp_color[1] * 255, $tmp_color[2] * 255);
}

for($x = 0; $x < $size; $x++) {
  for($y = 0; $y < $size; $y++) {
    imagesetpixel($image, $x, $y, $color[mandelbrot(-2 + ($x * 2.7 / ($size - 1)), -1.35 + ($y * 2.7 / ($size - 1)), $num_frames)]);
  }
}

imagegif($image);

imagedestroy($image);
?>

Solution

  • Your complex number square is wrong. You are overwriting the old value of a where it is needed again in the computation of b. So save it in a temporary variable.

    Also, the bailout value of 60 iterations is rather small, 200 would be more appropriate for this scale, for more detailed images it should be reasonably rapidly increase.

    Use a*a+b*b < 4 instead of the unnecessary square root. One could re-use the values of a*a and b*b which would also solve the problem of the temporary variable.

    norm=10
    while ... and norm < 4
        a2=a*a
        b2=b*b
        norm=a2+b2
        b=2*a*b+b_orig
        a=a2-b2+a_orig
    end