2010-09-16 151 views
5

一段時間以來,我一直對分形,它們背後的數學和它們可以產生的視覺感興趣。分形解釋

我只是不能真正弄清楚如何將數學公式映射到繪製圖片的代碼片段。
鑑於此公式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; 
} 

代碼是不完整的,只是顯示爲簡潔的主要部分迭代。

所以問題是:有人可以向我解釋數學與代碼相比如何?

編輯:爲了說清楚,我找到了幾十個解釋數學的資源,還有幾十個顯示代碼的資源,但是我找不到解釋這兩個資源的很好的解釋。

回答

16

聲明。我之前並不瞭解任何有關分形的知識,但總是想知道,所以我已閱讀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]); 
    } 

現在我們編寫一個返回true的函數,如果給定的(複雜)點$ C屬於Mandelbrot集

的點c屬於集合如果所有的點z = z^2 + c謊言與圈內半徑2.

  • 我們從複數z =(0,0)開始。
  • 在每一步我們計算z = z * z + c。
  • 如果modulus of 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

當然,這個代碼是無效的到了極點。它唯一的目的是理解數學概念。

+1

哇,謝謝你這個偉大的答案!今晚我會回到它,當我有更多的時間來真正嘗試和理解你剛剛寫的東西:) – 2010-09-16 13:20:02