當前位置:
首頁 > 知識 > 自繪Mandelbrot集合(三)

自繪Mandelbrot集合(三)

自繪Mandelbrot集合(三)



六、Java程序代碼

本節給出Java程序代碼(JavaScript版本見下節)。目前這個程序運行後只能繪出一個全紅的800*600的png格式圖像,並存在c:盤的temp文件夾下,名為"image.png"。如果你的c:盤下還沒有temp文件夾,就請先創建一下。


七、JavaScript程序代碼


要使用HTML內嵌JavaScript程序的朋友則請將下列代碼拷貝粘貼到純文本編輯器中(比如Windows下的Notepad),並存為html文件,可將其命名為「mandelbrot.html」,然後用網路瀏覽器打開。你應該能看到顯示有一個紅色的長方形的頁面。


八、語言相關部分

首先我們解決掉和所使用的計算機語言密切相關,所以在不同語言之間寫法很不同的部分。這些部分和Mandelbrot集合的繪製演算法其實沒什麼關係,屬於相應語言中的特定知識,我在此只稍微提一下,不作詳細解釋。


首先是特定的聲明,包括Java程序中「// (1)可調參數」前面的那些行,以及HTML文件中不包含在和之間段落內(即JavaScript程序部分)的那些行,大多屬於「如果懂這門語言就必定懂為什麼這麼寫」的內容,不多做解釋。除了HTML中的這句


這是可以看作是創建了一塊畫布掛在網頁上,畫布的標識號「id」為「image」。我們將要畫出來的圖像,就是要顯示在這塊畫布上。


然後是兩個版本也都有的「(4)程序入口」部分,程序開始運行時就從這裡進入,注意到JavaScript版本的入口在JavaScript程序部分的最上方,而Java版本則是從函數開始。


和具體繪圖相關的則是第(3)、(9)、(10)部分。

「(3)圖象緩存」部分都是定義了一個圖像緩存。兩種語言的繪圖方式都必須先在緩存中進行,繪完以後才一次性地用「(10)保存圖像」中的函數表現出來。Java版本的函數中的語句


是將圖像保存在「c: emp」文件夾下的image.png文件中,如果把上面語句中的兩個「png」都改成「jpg」,那麼存成的文件就是jpeg格式的。大家可以按自己喜好決定。而JavaScript版本的是將圖像緩存內容表現在剛才說到的標識號為「image」的畫布上,從而讓我們在瀏覽器上看到畫出的圖像。


「(9)在圖像像素(col, row)處畫上顏色rgb」則就是在第四節中提到的點彩畫法,呼叫函數就能在圖像緩存的第col列第row行那個像素上點上顏色代碼為rgb的顏色。關於以整數表示的RGB顏色代碼,我們在談論調色盤時會作較具體的介紹。特別值得提一句的是,如果仔細看程序代碼的話,在兩個版本中,當我們宣稱是在第row行畫點時,我們其實都是在圖像緩存的第IMAGEHEIGHT - row - 1行畫點。


這是因為在數學習慣上,Y軸的方向朝上,越往上縱坐標越大;而在計算機繪圖中,Y軸的方向通常則朝下。所以如果我們真的是在圖像緩存的第row行畫點的話,畫出來的Mandelbrot集合圖像會是上下顛倒的。


上述兩個版本的特定聲明部分,程序入口的第(4)部分以及和具體繪圖相關的第(3)、(9)、(10)部分一直到本文結束都不會再變動,我也不再加解釋。

九、繪圖演算法部分


剩下的(1)、(2)、(5)、(6)、(7)、(8)部分則是和Mandelbrot集合的繪製具體相關部分,如果對比兩個版本,可以發現它們很相似。只是由於兩種語言的對數據類型的處理方式不同,在Java語言中必須顯式地說明每個變數,每個函數的參數以及返回值的數據類型(,等),而在JavaScript語言中則只須作和聲明。相信有一定的計算機編程經驗,但沒有學過這兩種語言的讀者也容易看懂。


在「 (1)可調參數」部分定義了7個參數,以Java版本為例:


前兩個參數先略過,接下去4個參數定義了一個區域坐標,而最後的IMAGEWIDTH則定義了要繪製的圖像的寬度即橫向像素數。讀者可以在任何時候嘗試改變這些參數,尤其是試用本文許多插圖下的區域坐標定義,來驗證是否能繪出和插圖一致的區域的圖像。

「 (2)計算所得參數」中則計算了一些通過在(1)中的參數所計算得到的參數,比如所繪圖像高度,每個像素所代表的在複平面上的正方形的邊長等等。COFFSET和ROFFSET被用在下面要介紹的「(6)計算顏色」函數中,它們的計算公式也許對不熟悉這樣寫法的讀者來說有點奇怪:


可其實這無非是在說,如果IMAGEWIDTH是偶數(等於0的話),那麼COFFSET的值就是;如果IMAGEWIDTH是奇數,那麼COFFSET的值就是,但因為這是整數除法,要去掉餘數,所以結果其實和相同。


「(5)主程序」部分就是第四節中介紹的點彩繪圖原理。兩個針對行和列的循環遍歷圖片上的每個像素,循環體則是兩句無比簡單的呼叫:


第一句用我們將介紹的(6)中的函數來計算每個像素的顏色,再用前面介紹的(9)方法在圖像緩存的對應像素上畫出計算出來的顏色。兩個循環執行後,所有像素都繪製完畢,最後呼叫(10)來表現圖像。


上面提到的(1)、(2)、(5)部分,除了會變動可調參數的數值外,一直到本文結束也不再改變。


本文中我們將要重大修改的則是剩下的(6)、(7)、(8)部分,當然也是關鍵。不過目前看起來它們也簡單得很。仍以Java版本為例。


首先計算了兩個值cx和cy,它們其實就是第col列第row行那個像素所代表的複平面上的正方形的中心點的坐標,計算中用到了前面計算的參數COFFSET、ROFFSET和PIXELSIZE。「有WIDTH長度的線段,其中心點坐標為OX。線段被均勻分成IMAGEWIDTH段,試問第col段的中心點cx是多少?」這是個非常簡單的數學問題,我不作詳細推導了,只需注意「第n段」的n是從0開始算的,最左邊的是第0段。


計算出像素中心點在複平面上的坐標後,我們將用這個坐標代表的複數進行Mandelbrot集合定義中的迭代運算,即呼叫(7)中的函數,然後調用(8)中的調色盤函數來取得對應的顏色。也就是說,這個像素就被它的中心點代表了。


不過目前(7)和(8)中沒什麼具體的東西,無論cx和cy是什麼,最終(6)總是返回十六進位數FF0000,這是紅色的顏色代碼,所以繪出的圖是一片通紅。


枯燥的準備工作終於做完,下面我們將逐步填充和修改(6)、(7)、(8)部分,以達到我們繪製Mandelbrot集合圖像的目的。注意到上面兩個版本的程序的長度都大約是80行,為達到最終程序只有150行的目標,我們只能再填充70行程序。


(待續)


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 科學公園 的精彩文章:

人為什麼會信仰上帝?
從空氣中獲取水資源的新方法
推薦優質公眾號——博科園、天文地理
吸引力法則——極具吸引力的偽科學

TAG:科學公園 |

您可能感興趣

自繪Mandelbrot集合(五)
自繪Mandelbrot集合(四)
自繪Mandelbrot集合(六)
自繪Mandelbrot集合(七)
自繪Mandelbrot集合(二)
自繪Mandelbrot集合(一)
C 集合(Collection)
Java集合-LinkedList
Java集合——LinkedList
Java集合-ArrayList
Java集合——ArrayList
Hacking Tools搜羅大集合
前端數據存儲方案集合(cookie localStorage等)以及詳解(一)
WidgetLayout:一組繼承於 ViewGroup 的自定義容器集合
Java集合-HashSet
最佳cosplay鑒賞!PAX South遊戲展Coser大集合
《Fate/Apocrypha》第二集,黑方陣營英靈大集合
傳奇 Logo 大集合,Nike Presto X 「LEGACY」 定製版
見色起意!Nike Free RN Flyknit跑鞋大集合