Houdini JoyOfVex 教程05

05

Modulo(取模運算)

每個小學生都明白±*/,但通常沒學過編程的人不太用得到%。%是取模計算。相信你在小學就學過除法,除法會得到一個餘數。類似的,取模計算的值就是得到一個模數。

你問一個10歲小孩5除以2等於多少,他們都會告訴你結果等於2,餘1。所以咯,5%2 = 1。

你可能會問?那麼取模計算有毛用呢?它當然相當有用,因爲它能製造循環。比如說你用@ptnum/5,你會依次得到0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3…

@P.y = @ptnum % 5;

譯者注:取模運算和求餘運算好像有一點差別,自行查找相關資料,瞭解一下。不過基本都是用在正數的計算上,問題不大。

取模計算對於小數來說也是能用的,例如下面的代碼,你能得到一個直角三角形鋸齒狀(sawtooth)的數值排列結果(譯者注:點擊時間軸播放按鈕,觀察grid顏色變化,以及spreadsheet面板中Cd[r]值的變化。模數依次循環變化.

@Cd.r = @Time % 0.7;

很多效果都涉及到設置循環,取模運算給你提供了一種方便的方式來達到某種循環效果。
Making smooth things stepped via quantising(讓平滑效果轉變爲步幅階梯性變化)
首先寫下前幾節課的舊代碼,讓點的P.y值隨其離中心距離的遠近而變化:

float d = length(@P);
d *= ch('scale');
@P.y = d;

如前幾節課的看到的效果一樣,平面呈現了一種平滑的彎曲變化。想象一下,它的數值變化是連續的,類似:
1.0, 1.1, 1.2, 1.3, 1.4 … 1.8, 1.9, 2.0, 2.1, 2.2, 2.3 …

但如果我們移除小數點後面的部分呢:
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3

這樣的話,數值圖像彷彿像樓梯似的(steppy)變化。但如果原始數據非常小呢,例如從0.001慢慢增長到0.003?如果你像前面一樣,只是簡單粗暴地移除小數點後的數,那它們就全變成0咯,這可一點都不好玩。類似的,如果數很大呢,比如1000~4000?移除小數就基本顯現不出啥變化來。

這可咋整呢?別擔心,交給我吧!既然數值太大或者太小,移除小數起不到作用,那我們將該數值先乘以/除以一個數,他就變大/變小了,小數點也隨之左移或右移,此時我們移除小數,之後再將該數值除以/乘以一個數,這不是就OK了嗎。另外,移除小數用到的函數是trunc,你同樣可以在之前提到的網站查詢:

譯者注:例如一個數0.03567,如果直接移除小數點後的數則變爲0。而我們將其乘以1000,得到35.67,移除小數得35,再除以1000,得0.035,這樣就OK了。用同樣的方法,0.03555, 0.03875將變爲0.035,0.038,這樣就會呈現那種階梯狀的數值變化了。

float d = length(@P);
d *= ch('scale');
float f = ch('factor');
d /= f;
d = trunc(d);
d *= f;
@P.y = d;

這種丟失精確度(precision)的過程叫做量化(quantising)。
Faking trunc with a chramp(用樣條控制來僞造截取整數函數的效果)

將樣條調爲階梯狀就能做出類似效果。如上節課所講一樣,你最好給出2個滑竿控制(例如pre_scale和post_scale),一個用來將傳入chramp的變量x縮放到0~1的範圍(grid默認10個單位長,所以你的pre_scale可以調爲0.1),另一個在chramp計算過後,將其得到的y值從0-1縮放回你想要的值(比如將post_scale調爲10,和之前平面升高的最高點高度對應)。

譯者注:可查看spreadsheet的P[y]值觀察一下變化。

float d = length(@P);
d *= ch('pre_scale');  // 也可使用fit函數,例如d = fit(d,  0, 7.07107,  0, 1);
d = chramp('my_stepped_ramp', d);
d *= ch('post_scale');  // 若用fit,則同理倒回去,d = fit(d,  0,1,  0, 7.07107);
@P.y = d;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章