2010-09-16 11 views
5

Desde hace un tiempo me interesan los fractales, las matemáticas detrás de ellos y las imágenes que pueden producir.Fractales explicados

Simplemente no puedo entender cómo mapear la fórmula matemática con un fragmento de código que dibuja la imagen.
dado esta fórmula para el conjunto de Mandelbrot: Pc(z) = z * z + c
¿Cómo se compara con el siguiente código:

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

Código no es completa, simplemente muestra la parte principal iteración por razones de brevedad.

Entonces la pregunta es: ¿podría alguien explicarme cómo se compara la matemática con el código?

Editar: Para ser claros, he encontrado docenas de recursos que explican las matemáticas, y docenas de recursos que muestran el código, pero en ninguna parte puedo encontrar una buena explicación de los dos combinados.

Respuesta

16

Descargo de responsabilidad. Antes no sabía nada de fractales, pero siempre quise saberlo, así que leí el wikipedia article y decidí escribir lo que encontré aquí. Como dicen, si quieres entender algo, intenta explicárselo a otra persona. ;)

Bien, vamos a operar en números complejos. Un número complejo es en realidad un par de números (reales), entonces, para nosotros los programadores php, que sea una matriz de dos elementos.

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

Ahora tenemos que decirle a php cómo hacer aritmética en nuestros números complejos. Necesitaremos el operador de suma, multiplicación y mod ("norma"). (ver http://mathworld.wolfram.com/topics/ComplexNumbers.html para más detalles).

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

Ahora escribimos una función que devuelve verdadero si el dado (complejo) Punto de $ c pertenece al conjunto de Mandelbrot

Un punto c pertenece al conjunto si todos los puntos z = z^2 + c se encuentran en el interior del círculo con el radio 2.

  • Comenzamos con el número complejo z = (0, 0).
  • En cada paso calculamos z = z * z + c.
  • Si modulus of z> 2 - es decir, estamos fuera del círculo - el punto NO está en el conjunto
  • De lo contrario, repita el paso.

Para evitar que se repita indefinidamente, limite el número máximo de iteraciones.

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

El resto no tiene nada que ver con las matemáticas y es bastante obvio

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

Resultado

alt text

Por supuesto, este código no es efectiva hasta el extremo. Su único propósito es entender el concepto matemático.

+1

¡Guau, gracias por esta gran respuesta! Volveré a hacerlo esta noche cuando tenga más tiempo para tratar de comprender lo que acabas de escribir :) –

Cuestiones relacionadas