分形程序高級技巧入門教程--第一到四章
[email protected]
摘要:
本系列文章是寫給分形編程愛好者的一個入門教程;文章章節包括(規劃中的,可能增刪):
一.複數迭代的mandelbrot集合; 二.顏色平滑的簡單週期算法; 三.迭代逃逸次數插值的顏色平滑;
四.使用sin函數做顏色平滑; 五.一個更有效的迭代逃逸次數插值公式; 六.使用誤差擴散來杜絕色差感;
七.集合內部的顏色; 八.julia集合; 九.迭代生成的複數值的插值;
十.迭代生成的複數值的高階插值; 十一.圖形的放大和旋轉; 十二.複數初始值的變換;
十三.固定顏色表; 十四.設計圖案的映射; 十五.紋理映射; 十六.並行計算;
十七.更多的迭代方程和顏色方案; 十八.高次mandelbrot集合; 十九.其他分形的介紹、分形動畫
正文:
(1-4章完整項目源代碼: http://cid-10fa89dec380323f.office.live.com/self.aspx/.Public/hssFractal1%5E_4.zip
)
(我的其他分形相關文章: http://blog.csdn.net/housisong/category/382024.aspx
)
一.複數迭代的mandelbrot集合
對於複數函數 f(z)=z^2+z0; 給定任意的z0,迭代可以得到序列:z0^2 + z0,
z0^4 + 2*z0^3 + z0^2 + z0,...... 我們把經過任意次迭代以後而不發散的z0定義爲
Mandelbrot集合; 把複數方程改寫爲對應的實數方程:
x(i+1)=x(i)*x(i)-y(i)*y(i)+x(0); //實部
y(i+1)=x(i)*y(i)*2+y(0); //虛部
Mandelbrot迭代函數:我們認爲迭代一定次數max_iter以後,沒有逃逸的點就屬於集合,返回max_iter;
如果發生逃逸,返回當前迭代次數,代碼如下: (當|Z(i)|^2>=4時,點必然逃逸)
迭代逃逸次數映射成顏色值:我們根據不同的逃逸次數,簡單生成一個對應的RGB顏色值,代碼如下:
我們把複平面上以點(x0,y0)爲中心橫軸2*r寬的複數區域均勻採樣with(寬)*height(高)個點,
獲取其Mandelbrot迭代逃逸次數,並映射成相應的顏色填充到一個with(寬)*height(高)的圖片中,代碼如下:
調用該函數生成一幅圖片,代碼如下: (尺寸640x480,中心點(-0.5,0),r=2;最大迭代次數1000)
生成的圖片如下:
二.顏色平滑的簡單週期算法
直接的%求餘容易造成較強的顏色階梯,我們用一個平滑一點的函數來處理迭代值到顏色的轉化:
color=(i%510)-255; 當i連續變化的時候,得到的color值也是連續變化的:
(其他代碼相同)
生成的圖片如下:
對於相鄰的逃逸次數,現在的顏色還不夠平滑,可以把那些*乘法系數取消掉,這樣就能保證得到
的顏色的平滑(但顏色的對比就比較小了):
生成的圖片如下:
三.迭代逃逸次數插值的顏色平滑
相鄰點的逃逸次數差爲1,對應到顏色最大亮度的1/255時才能看起來平滑(如:coloring1_s);
如果想增大他們之間的顏色對比,又有可能產生顏色梯度(如:coloring1); 我們如何同時滿足
這兩個要求呢?答案是對逃逸次數進行插值!
逃逸次數
插值公式: i +1-log(log(|Z|))/log(P); (P爲複數方程的指數,這裏爲2)
這是一個近似插值公式,有一定的誤差;如果多迭代幾次的話,可以減小該公式的誤差;
(公式來源參見: http://linas.org/art-gallery/escape/ray.html )
代碼如下: (增加了迭代次數)
生成的圖片如下:
四.使用sin函數做顏色平滑
sin函數也是個不錯的顏色平滑調節函數,函數值連續,處處可導...
產生的顏色更柔和一些,代碼如下:
生成的圖片如下: