所以讓我來把CCC的講義案例做簡單的白話文翻譯,
你就會知道程式碼就跟學任何語言一樣,由語法(邏輯順序)跟單字(指令)組成爾爾.
有鑑於CCC常說學長教學寫了寫就不寫了的事會發生在我身上,
因此我要非常不負責的告訴大家,林杯想寫什麼就寫什麼,
你要學什麼基礎就去把前面的processing教學給我看完,
因為我只會拿processing裡的指令跟rhinoscript做相似的比對,
這種東西就是要會舉一反三麻是不是? 速西ㄟ~~~~
........................................... :-x
如果你有跟著我之前學processing一樣從零開始,
那我現在講得你應該一點就通,
如果你看得有點吃力,代表你之前不好好砸時間下去摸,
現在趕快回去把之前的processing教學看一看還來得及.
師父叫你蹲馬步跟挑水桶不是沒有道理滴!
好了,誠如CCC所說的,grasshopper在做for loop這種東西上是比較弱的,
(幹,for loop是什麼都不知道就趕快看這裡)
相對如果你只是做單純的遞歸,那grasshopper的確會比較方便.
簡單來說,如果你只是要做形,那就用grasshopper,
如果要做較偏向前因後果的空間關係演算法,那rhinoscript會比較吃香.
這篇要講的就是square fractal,方塊碎形,以下.
---------------------------------------------------------------------------------------------------------
Call Rhino.EnableRedraw(False)
Call Fractal_01(0,0,30,2)
Call Rhino.EnableRedraw(True)
Sub Fractal_01(X,Y,L,n)
Dim a,b,c,d,E
a = Array(X+L/2,Y+L/2,0)
b = Array(X-L/2,Y+L/2,0)
c = Array(X-L/2,Y-L/2,0)
d = Array(X+L/2,Y-L/2,0)
If n > 0 Then
Call Rhino.AddSrfPt(Array(a,b,c,d))
E = 0.75 * L
Call Fractal_01(X+E,Y+E,L/2,n-1)
Call Fractal_01(X-E,Y+E,L/2,n-1)
Call Fractal_01(X-E,Y-E,L/2,n-1)
Call Fractal_01(X+E,Y-E,L/2,n-1)
End If
End Sub
基本上我們要將程式碼先拆成兩部份來看.
Call Rhino.EnableRedraw(False)
Call Fractal_01(0,0,30,2)
Call Rhino.EnableRedraw(True)
Sub Fractal_01(X,Y,L,n)
Dim a,b,c,d,E
a = Array(X+L/2,Y+L/2,0)
b = Array(X-L/2,Y+L/2,0)
c = Array(X-L/2,Y-L/2,0)
d = Array(X+L/2,Y-L/2,0)
If n > 0 Then
Call Rhino.AddSrfPt(Array(a,b,c,d))
E = 0.75 * L
Call Fractal_01(X+E,Y+E,L/2,n-1)
Call Fractal_01(X-E,Y+E,L/2,n-1)
Call Fractal_01(X-E,Y-E,L/2,n-1)
Call Fractal_01(X+E,Y-E,L/2,n-1)
End If
End Sub
黃色的部份那些call就是在叫指令的意思,
所以我們會說call taxi意思是叫計程車不是沒有道理的.
橘色的部份在processing中就是所謂的void,一種可撰寫指令的空集合.
(如果你忘了void是什麼請看這裡)
所以Sub ______ ()
的底線就是你集合的名稱,
括號內就就是你會在集合內用到的參數代號.
且讓我們先一行一行看橘色的部分,
噢對了,在processing裡//之後代表無效程式碼,在rhinoscript內則是在'之後.
Sub Fractal_01(X,Y,L,n)
'有一個叫做Fractal_01的集合,這集合內需要代入X,Y,L,n這四個數.
Dim a,b,c,d,E
'dim就跟processing內一樣,你有什麼數需要被定義就需要先來個dim.
a = Array(X+L/2,Y+L/2,0)
b = Array(X-L/2,Y+L/2,0)
c = Array(X-L/2,Y-L/2,0)
d = Array(X+L/2,Y-L/2,0)
'這四行就是在到時有X,L等數被代入時,a,b,c,d就會有各自的值.
If n > 0 Then
'當代入n的數大於零時則會啟動下面的三項事情
Call Rhino.AddSrfPt(Array(a,b,c,d))
'當n>0時,執行AddSrfPt這指令,基本上就是一個需要三到四個點構成一個面的指令,
'如果你不知道這些指令是幹麻的,在rhinoscript editor > help > index下搜尋
E = 0.75 * L
'當n>0時,E = 0.75 * L,這單純是演算碎形時的需要
Call Fractal_01(X+E,Y+E,L/2,n-1)
Call Fractal_01(X-E,Y+E,L/2,n-1)
Call Fractal_01(X-E,Y-E,L/2,n-1)
Call Fractal_01(X+E,Y-E,L/2,n-1)
'當n>0時,分別call fractal_01四次,只是原本代入的X,Y,L,n會變
'你可以看到最後一項n-1,這就是為了呼應前面if n > 0所做的應對,
'所以我們知道總共在算過兩次之後n > 0就不成立了
End If
'因為用到if就要end if
End Sub '因為用到一個sub就要end sub
好,如果你到上面基本的理解都沒問題,
我們就可把黃色部份的數代入橘色內看看CCC到底在想什麼.
Call Rhino.EnableRedraw(False)
'我不太知道EnableRedraw這指令到底要怎麼用,但基本上不影響運算
Call Fractal_01(0,0,30,2)
'我們由此可知一開始代入X,Y,L,n這四個數的值是0,0,30,2
Call Rhino.EnableRedraw(True)
'等我了解這指令再解釋
讓我們看看電腦是怎麼看這些script的,
因為我們知道n一開始為2,所以會做兩次運算.
首先(0,0,30,2)代入(X,Y,L,n)後
a = Array(X+L/2,Y+L/2,0)
b = Array(X-L/2,Y+L/2,0)
c = Array(X-L/2,Y-L/2,0)
d = Array(X+L/2,Y-L/2,0)
會變成
a = Array(0+30/2,0+30/2,0)
b = Array(0-30/2,0+30/2,0)
c = Array(0-30/2,0-30/2,0)
d = Array(0+30/2,0-30/2,0)
也就是
a = Array(15,15,0)
b = Array(-15,15,0)
c = Array(-15,-15,0)
d = Array(15,-15,0)
而因為n=2是> 0的,因此會發動Call Rhino.AddSrfPt(Array(a,b,c,d))
也因此我們知道這個分別在四象限的點會連成一個面,
一個邊長為30的正方形.
同時,E = 0.75 * L一算即是E = 0.75 * 30 = 22.5
而之下的
Call Fractal_01(X+E,Y+E,L/2,n-1)
Call Fractal_01(X-E,Y+E,L/2,n-1)
Call Fractal_01(X-E,Y-E,L/2,n-1)
Call Fractal_01(X+E,Y-E,L/2,n-1)
就變成
Call Fractal_01(0+22.5,0+22.5,30/2,2-1)
Call Fractal_01(0-22.5,0+22.5,30/2,2-1)
Call Fractal_01(0-22.5,0-22.5,30/2,2-1)
Call Fractal_01(0+22.5,0-22.5,30/2,2-1)
意即
Call Fractal_01(22.5,22.5,15,1)
Call Fractal_01(-22.5,22.5,15,1)
Call Fractal_01(-22.5,-22.5,15,1)
Call Fractal_01(22.5,-22.5,15,1)
因此這四個Call Fractal_01又會分別再去生產四個方形,
Call Fractal_01(22.5,22.5,15,1)的方形是
a = Array(22.5+15/2,22.5+15/2,0)
b = Array(22.5-15/2,22.5+15/2,0)
c = Array(22.5-15/2,22.5-15/2,0)
d = Array(22.5+15/2,22.5-15/2,0)
即
a = Array(30,30,0)
b = Array(15,30,0)
c = Array(15,15,0)
d = Array(30,15,0)
其他三個同理,之後分裂越來越多只是把n加大而已.
下圖則是Call Fractal_01(0,0,30,6)的結果
但寫到此刻,我發現一個地方不對勁,
不合邏輯令我百思不得其解,你發現了嗎?
沒有留言:
張貼留言