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;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章