大廳的燈光暗下來(lái),帳幕徐徐打開(kāi),銀幕上出現(xiàn)了根據(jù)J.R.R.Tolkien的三部曲“Lord of the Rings”所改編的電影。Frodo在一個(gè)開(kāi)闊的峽谷里溜達(dá)著。遠(yuǎn)處,鋸齒狀的冰雪覆蓋著的山峰聳入云端。近處有些不知是什么種類的奇花異木在陽(yáng)光下閃爍。轉(zhuǎn)眼,屏幕上的奇景變成了一個(gè)男巫凝視著一只水晶球,在這球體的中央出現(xiàn)了一個(gè)堡壘,火焰正從它的城垛里竄出來(lái)。
雖然現(xiàn)在還很難說(shuō)Frodo是否會(huì)在這樣的電影里出現(xiàn),但我肯定那些山峰、樹(shù)木、水晶球以及火焰都會(huì)奇妙地出現(xiàn)在銀幕上。這個(gè)成就主要將歸功于Pixar公司(即從前的Lucasfilm計(jì)算機(jī)繪圖實(shí)驗(yàn)室)所開(kāi)發(fā)的軟件和硬件。有家用計(jì)算機(jī)的讀者都能夠在計(jì)算機(jī)上作出基本類似于這些東西的圖形來(lái)。由于本文篇幅所限,不能在此對(duì)水晶球和火焰作一個(gè)廣泛深入的論述,但還是能夠揭示產(chǎn)生它們的基本原理。
在上面描述的假想的電影中,我們可以把攝像機(jī)移向Frodo身后的那些山峰上。人們可能從來(lái)沒(méi)有見(jiàn)過(guò)比這些山峰更令人生畏的大片陸地了。每一個(gè)大的山峰都由一些較小的山峰構(gòu)成,而這些較小的山峰又由比它們更小的山峰組成,如此下去就形成了一種小山峰的無(wú)窮回歸。即使一個(gè)有皮質(zhì)腳的滴水嘴一樣的海怪站在這樣一個(gè)犬牙般的地方也會(huì)感到難受(見(jiàn)彩圖11)。
原則上,這樣的一種山的圖形是容易作出來(lái)的。為簡(jiǎn)便起見(jiàn),我假定這山覆蓋了一個(gè)三角形的地面。找出每條邊的中點(diǎn),用三條線段把這三個(gè)中點(diǎn)連起來(lái)。就把這三角形分成了四個(gè)較小三角形。用同樣的辦法再分這四個(gè)小三角形。這一過(guò)程不斷進(jìn)行,直到達(dá)到分辨率極限或計(jì)算時(shí)間極限為止。結(jié)果是得到一大堆令人感到枯燥無(wú)味的三角形。如果要使這圖形變得生動(dòng)一些,可以在作圖過(guò)程中加進(jìn)一條有關(guān)垂直方向上的規(guī)則:每當(dāng)新的中點(diǎn)畫(huà)在圖上時(shí),就使其向上或向下移動(dòng)某一隨機(jī)量。通常這個(gè)隨機(jī)數(shù)必須隨三角形的逐漸變小而減少。這一規(guī)則把那些三角形變成弄皺了的山峰和褶皺(見(jiàn)圖)。
為什么這一種方法會(huì)作出那樣逼真的山峰圖案呢?答案在于這個(gè)過(guò)程中產(chǎn)生了一個(gè)分?jǐn)?shù)維圖形,即當(dāng)圖案不斷放大時(shí)會(huì)顯露出更多的細(xì)節(jié)的圖形。分?jǐn)?shù)維形態(tài)在自然界似乎是隨處可見(jiàn)。我們可以用一個(gè)關(guān)于海岸線的例子解釋分?jǐn)?shù)維圖形的基本概念。假設(shè)我們要用一根l000米長(zhǎng)的測(cè)量桿測(cè)量出法國(guó)海岸線的長(zhǎng)度,那么就得沿著海灘向前一桿一桿地進(jìn)行艱難的測(cè)量,同時(shí)數(shù)出有多少個(gè)l000米。然而這樣會(huì)把許多小的海灣和海岬遺漏掉,所以用這種辦法測(cè)出的最后得數(shù)是不那么準(zhǔn)確的。用一根l米長(zhǎng)的測(cè)量桿重復(fù)這一過(guò)程,會(huì)得出一個(gè)更精確、數(shù)字更大的結(jié)果。但即使如此,也有大量的小海灣和岬地被遺漏掉了。無(wú)疑,用一根l厘米長(zhǎng)的測(cè)量桿結(jié)果就會(huì)更為精確。
一般規(guī)律是,當(dāng)測(cè)量桿變小時(shí),測(cè)出的海岸線長(zhǎng)度會(huì)增大。測(cè)出的長(zhǎng)度與測(cè)量桿桿長(zhǎng)之比率為一個(gè)專門(mén)值,這個(gè)值稱為分?jǐn)?shù)維。分?jǐn)?shù)維與通常說(shuō)的維不同,它往往被表達(dá)成一個(gè)分?jǐn)?shù),而不是一個(gè)整數(shù)。例如我們討論的海岸線的維數(shù)可能就是一個(gè)3/2的分?jǐn)?shù)維。可以把這樣的一種形狀想象成一個(gè)介于一維形狀(直線)和二維形狀(平面)之間的中間形狀。如果海岸線比較直,其分?jǐn)?shù)維就接近于1。如果海岸線很曲折,其分?jǐn)?shù)維就接近于2,此時(shí)它幾乎填滿一個(gè)二維平面。
自然界的分?jǐn)?shù)維模型實(shí)際上隱含了細(xì)節(jié)的無(wú)窮回歸。從計(jì)算機(jī)繪圖的角度來(lái)看,無(wú)窮回歸是無(wú)關(guān)緊要的問(wèn)題;只要景物看來(lái)是具有各級(jí)放大水平上的細(xì)節(jié)就行了。在達(dá)到屏幕分辨率的極限之前,計(jì)算機(jī)上生成的山的特征就與上述分割過(guò)程中最終所得的三角形的特征一樣精細(xì)。完整的山峰繪制算法太長(zhǎng)太復(fù)雜,無(wú)法在此作足夠詳細(xì)的介紹。但有一個(gè)簡(jiǎn)單的程度可以繪出Mandelbrot峰的斷面,它稱為MOUNTAIN。該程序體現(xiàn)了沿垂直軸隨機(jī)移動(dòng)中點(diǎn)這一基本早想。開(kāi)始時(shí)是一條水平線段。確定其中點(diǎn),使其向上或向下移動(dòng)一段隨機(jī)地確定的距離,然后把由此產(chǎn)生的兩個(gè)線段再分,并使其各自中點(diǎn)也按此規(guī)則移動(dòng)。用類似于再分三角形的方法可把這一過(guò)程不斷地進(jìn)行下去。
程序MOUNTAIN有兩個(gè)數(shù)組,叫做points和lines。其作用是保持計(jì)算機(jī)屏幕上的山的輪廓。每個(gè)數(shù)組分別有兩列和足夠多的行(比如說(shuō)2048行)以方便地調(diào)整屏幕分辨率;points的兩列是坐標(biāo)值,而lines的兩列則是下標(biāo)。每條線段定義為數(shù)組points中表明該線段終點(diǎn)坐標(biāo)的一對(duì)位置。觀察一個(gè)普通的多邊形通過(guò)一連串的再分后形成山的輪廓這一過(guò)程是非常有趣的,所以程序MOUNTAIN使每一次圖案的形成都處于用戶的控制下。在—次主循環(huán)結(jié)束時(shí),程序詢問(wèn)用戶是否需要另一次迭代,如果回答是肯定的,那么執(zhí)行會(huì)再返回此程序的開(kāi)頭。
主循環(huán)的作用是把當(dāng)前的點(diǎn)與線段的集合變成大1倍的新集合。為實(shí)現(xiàn)這一點(diǎn),它一次一行地對(duì)數(shù)組lines進(jìn)行掃描,查尋其對(duì)應(yīng)點(diǎn)的下標(biāo)并從數(shù)組poinlts中檢索出它們的坐標(biāo)。在已知某一給定線段的兩個(gè)端點(diǎn)坐標(biāo)后,程序就可以計(jì)算出該線段的中點(diǎn)坐標(biāo),同時(shí)隨機(jī)地改變y坐標(biāo)的值。下面所列出的算法過(guò)程為程序的編制提供了充分的基礎(chǔ),其中變量j和k是指數(shù)組points和lines中當(dāng)前正保持著再分的最新結(jié)果的那些“行”。變量pts和lns記錄在進(jìn)入主循環(huán)之前構(gòu)成山的點(diǎn)和線段的數(shù)目。開(kāi)始時(shí)j等于pts,k等于lns。下標(biāo)i從1到lns。
MOUNTAIN程序的這一部分在很大程度上是不言自明的。當(dāng)?shù)趈點(diǎn)的坐標(biāo)計(jì)算出來(lái)后,下標(biāo)j就被存貯起來(lái)作為第i條線段的第二個(gè)點(diǎn)和第k條線段的第一個(gè)點(diǎn)。第i條線段的第一個(gè)點(diǎn)與其原來(lái)的一樣,而第k條線段的第二個(gè)點(diǎn)與第i條線段原來(lái)的第二個(gè)點(diǎn),即帶有下標(biāo)b的那個(gè)點(diǎn)相同。當(dāng)循環(huán)最終計(jì)算后,pts和lns必須分別復(fù)置為j和k的最新值。變量range是在程序的開(kāi)頭由用戶確定各再分點(diǎn)在垂直方向上隨機(jī)移動(dòng)量的最大值。每次循環(huán)結(jié)束時(shí),該變量就要除以2,使得這一隨機(jī)移動(dòng)量與線段尺寸成比例地減小。函數(shù)random(range)用于表示在0和變量range的當(dāng)前值之間所選擇一個(gè)隨機(jī)數(shù)。
如果Frodo身后的那些山峰是令人難忘的,那么,他周圍的村木和植物就更是令人難忘。它們既逼真又奇特。之所以逼真,是因?yàn)樗鼈冇信c真實(shí)植物一樣的分枝,而之所以奇特是因?yàn)樗鼈儾皇浅R?jiàn)的物種。大概是圖形設(shè)計(jì)者有太多的參數(shù)可以任他使用,因此他禁不住要?jiǎng)?chuàng)造一些新的植物種類。
這些新的植物種類被叫做“嫁接”(graftal)植物,因?yàn)樗鼈兪窃趫D形(graph)的基礎(chǔ)上形成的,且有內(nèi)在的的分?jǐn)?shù)維性質(zhì)。這里所謂的“內(nèi)在分?jǐn)?shù)維性質(zhì)”,指的是用于生成植物圖案的基本拓?fù)涮卣鞯囊?guī)規(guī)則可以(但實(shí)際上沒(méi)有)應(yīng)用于屏幕分辨率的極限。簡(jiǎn)言之,植物的細(xì)枝條不會(huì)無(wú)限地回歸成更小的枝條。一旦作為植物的基礎(chǔ)的圖形發(fā)展起來(lái),計(jì)算機(jī)就能用大小、顏色、厚度、質(zhì)地等解釋植物的圖形,從而把它變換成無(wú)數(shù)的令人信服的植物種類。
某一給定植物所據(jù)以形成的圖形是由L系統(tǒng)產(chǎn)生,這種系統(tǒng)是丹麥生物學(xué)家和數(shù)學(xué)家Aristid Lindenmeyer在1968年提出的一種語(yǔ)法類別。一個(gè)L系統(tǒng)實(shí)際就是一套用于從舊的字符串中推導(dǎo)新的字符串的規(guī)則。例如,根據(jù)下列規(guī)則,用數(shù)字0和1以及符號(hào)[和]能夠生成一系列復(fù)雜的植物:
0→l[0]1[0]0
l→11
[→[
]→]
為了弄清如何應(yīng)用這些規(guī)則,我們從由單個(gè)的符號(hào)0組成的字符串開(kāi)始。將箭頭左邊的每一個(gè)符號(hào)都用與其對(duì)應(yīng)的右邊的符號(hào)來(lái)代替,就可以一個(gè)接一個(gè)地得到下列的字符串:
01[0]1 [0]011[1[0]l[0]0]ll[1[0]1[0]0]1[0]l [0]0
把每個(gè)數(shù)字(0或1)當(dāng)作一條線段,每個(gè)括號(hào)當(dāng)作一個(gè)分支點(diǎn),就可把這樣的字符串變換成樹(shù)一樣的圖形。0和1所代表線段的長(zhǎng)度相等,其區(qū)別在于0線段的外端上要加一片葉子,而1線段上則什么也不加。
例如字符串1[0]1[0]0的莖是由三個(gè)不在括號(hào)內(nèi)的符號(hào)組成的。最下面的是1線段,中間也是1線段,頂部則是0線段。兩根枝條(每根均是一條0線段)從莖上長(zhǎng)出來(lái)。第一根枝條長(zhǎng)在第一條1線段上,第二根枝條則長(zhǎng)在第二條1線段上。讀者可以試畫(huà)一下樹(shù)莖最初幾次生成的圖案。為了使植物更逼真,對(duì)這個(gè)模型可以加上另外一些解釋性的規(guī)則;例如,對(duì)于任何給定的莖(不管它是否主莖),都可以使枝條輪流地從左右兩側(cè)長(zhǎng)出。
一個(gè)叫PLANT的由兩部分組成的程序產(chǎn)生上述序列中的第n個(gè)字符串,然后把它表示成一個(gè)線段圖。在該程序的第一階段,PLANT將它所生成的字符串保存在被稱為String A及string B的兩個(gè)符號(hào)數(shù)組中。每一代植物圖形輪流地占據(jù)兩個(gè)數(shù)組中的一個(gè),即某一數(shù)組中所存貯的那一代是由另一數(shù)組中所存貯的上;代得來(lái)的。也不一定非要在數(shù)組中存貯符號(hào)。只要程序的代換過(guò)程是正確的,數(shù)字0,l,2和3也完全可以。
L系統(tǒng)規(guī)則在條件語(yǔ)句中體現(xiàn)出來(lái);例如可以采用下面這段算法編碼把StringA的第i位上的1個(gè)0變成string B中的九個(gè)新的符號(hào):
如果stringA(i)=0,那么
stringB(j)←1
stringB(j+1)←2
stringB(j+2)←0
stringB(j+3)←3
stringB(j+4)←1
stringB(j+5)←2
stringB(j+6)←0
stringB(j+7)←3
stringB(j+8)←0
j←j+9
這里0和1代表它們自己,而2和3分別代表[和],如果string A的第i個(gè)符號(hào)是0,那么,程序把序列l(wèi),2,0,3,l,2,0,3,0插入數(shù)組string B中以下標(biāo)j(即數(shù)組string B的尚未填入符號(hào)的第;個(gè)年置)開(kāi)頭的九個(gè)連續(xù)位置上。程序PLANT的第一階段中的一個(gè)單循環(huán)就含有四個(gè)上述的條件語(yǔ)句,每個(gè)語(yǔ)句相應(yīng)于可能遇到的一個(gè)符號(hào)。循環(huán)用下標(biāo)j來(lái)指出當(dāng)前這一代中正被處理的那個(gè)符號(hào)。循環(huán)執(zhí)行的次數(shù)依用戶的愿望而定。在每一次生成后,程序PLANT會(huì)詢問(wèn)用戶是否希望另一個(gè)更長(zhǎng)的字符串。
PIANT的第二個(gè)階段(即繪圖階段)把第一個(gè)階段產(chǎn)生的字符串變換成一個(gè)圖形。它循環(huán)地執(zhí)行這一過(guò)程:只要左括號(hào)(或2)沒(méi)有出現(xiàn),它就在一個(gè)給定方向上繪出一系列線段。當(dāng)碰到某一對(duì)括號(hào)中的左括號(hào)時(shí)。程序就在一個(gè)新的方向(從前一個(gè)方向反時(shí)針轉(zhuǎn)45°)上繪出后面的線段。當(dāng)對(duì)應(yīng)的右括號(hào)出現(xiàn)后,這一過(guò)程就終止。這時(shí)畫(huà)出一片葉子,它的形狀和顏色都留給讀者去想象。第二個(gè)左括號(hào)的出現(xiàn)使該程序又重復(fù)進(jìn)行。只是現(xiàn)在的方向是順時(shí)針45°。其他的工作都是自動(dòng)進(jìn)行的。
PIANT用了一個(gè)隨被繪出的植物的復(fù)雜性而定的比例因數(shù)。例如,第n代植物的高度大約為2n條線段,如果屏幕的高是200個(gè)像元,那么每根線段就必須短于200/2n雄心勃勃的讀者們無(wú)疑會(huì)嘗試生成語(yǔ)法、枝條角度及葉片形狀等方面的新花樣。如果具有這些新花樣的圖案在同一屏幕上生成,植物和樹(shù)木的風(fēng)景就會(huì)出現(xiàn)了(當(dāng)然不是很逼真的)。
Pixar繪圖計(jì)算機(jī)的心臟是一個(gè)有24兆字節(jié),2000×2000像元的存貯器,其分辨率對(duì)大多數(shù)應(yīng)用是足夠的。此外,每個(gè)像元由48個(gè)存貯位表示,足夠存貯色采和透明度方面的信息。Pixar繪圖計(jì)算機(jī)的大容量存貯器由四個(gè)高速并行完全可編程序的處理機(jī)操縱。它們每秒鐘能執(zhí)行約4000萬(wàn)條指令,其速度比普通的計(jì)算機(jī)大幾個(gè)數(shù)量級(jí)。顯示裝置與存貯器問(wèn)的數(shù)據(jù)交換速度可達(dá)每秒4.8億個(gè)字節(jié)。
Pixar繪圖計(jì)算機(jī)預(yù)定用于醫(yī)學(xué)成像、遙感、工程設(shè)計(jì)及動(dòng)畫(huà)片制作這些領(lǐng)域中。也許還會(huì)用來(lái)制作我在本文開(kāi)頭所描述的假想電影。
本文來(lái)自:逍遙右腦記憶 http://www.yy-art.cn/gaozhong/107344.html
相關(guān)閱讀:2014高考備考復(fù)習(xí)數(shù)學(xué)有哪些誤區(qū)