Houdini學(xué)習(xí)筆記029_一個節(jié)點(diǎn)實(shí)現(xiàn)隨機(jī)行走

今天我們來做如下所示的random walk(隨機(jī)行走)效果,全程只用到一個Attribute Wrangle節(jié)點(diǎn)。

下面是VEX腳本,Run Over方式選擇Detail (only once)。

整體思路很簡單,設(shè)定一個初始點(diǎn),每步走一格。每步行走的方向在上、下、前、后、左、右中六選一。如果下一步位置已經(jīng)走過,則重新選方向。
我們先從最簡單的情況入手——只朝一個方向走。
(一)設(shè)置初始點(diǎn):
vector p0 = 0;
矢量如果只給一個數(shù)值,如0,等同于{0,0,0}。addpoint函數(shù)添加點(diǎn),編號返回給整型變量npt。

(二)設(shè)定方向:
vector dir = {1,0,0};
每步行走用for循環(huán)語句實(shí)現(xiàn),這里設(shè)置了兩個參數(shù),一個是總步數(shù)steps,一個是步長step length,寫法如下。記得每次循環(huán)最后用新的點(diǎn)坐標(biāo)作為下一次循環(huán)起始的點(diǎn)坐標(biāo),即:
p0 = p1;

(三)連點(diǎn)成線:
前面的筆記中已經(jīng)講過多次。每次添加點(diǎn)時,返回的編號npt用append函數(shù)添加到一個數(shù)組(pts[ ])中。最后用addprim函數(shù)畫線:
addprim(geoself(), "polyline", pts);

第一個目標(biāo)完成~

下面,我們讓每一步行走的方向是隨機(jī)的。
方法是先設(shè)定一個方向的數(shù)組,定義上下前后左右六個方向。
vector dir[ ] = array({1,0,0}, {-1,0,0}, {0,1,0}, {0,-1,0}, {0,0,1}, {0,0,-1});
每次循環(huán)時,從六個方向中隨機(jī)選取一個,使用的是rand函數(shù),另外可以加一個seed種子來產(chǎn)生變化,寫法如下:
int rd = int(rand(i + chf("seed")) * 6);
隨機(jī)數(shù)乘以6再取整得到的就是0、1、2、3、4、5中的任一數(shù)值,而后方向矢量取值dir[rd]即可。得到的結(jié)果如下——

隨機(jī)方向是實(shí)現(xiàn)了,但現(xiàn)在的問題是,不能避免走回頭路。即分岔點(diǎn)處走了不止一次。所以在走之前我們還要加個判斷條件,確保下一個位置沒走過。
我的思路是這樣的,把之前走過的點(diǎn)的位置放在一個數(shù)組中,每走新的一步之前,將下一個目標(biāo)的位置與數(shù)組中已有點(diǎn)位置進(jìn)行比較,如果有重合,則重新選擇行走的方向。判斷位置是否重合可以用distance函數(shù),如果距離小于某個很小的值,就認(rèn)為兩點(diǎn)是重合的。
比較下一個點(diǎn)與之前走過的點(diǎn)的位置也要用到for循環(huán)(每一個都要計(jì)算距離),dis如果小于0.001則認(rèn)為是0,否則認(rèn)為是1。每次結(jié)果相乘,如果有一個是0,那么最終結(jié)果必定是0。說明這個位置之前走過,重走!

重走的方式也很直接,用continue跳出當(dāng)前循環(huán),直接進(jìn)入下一個循環(huán)即可。如果行走成功,那么用append函數(shù)將新的點(diǎn)p1放進(jìn)dots數(shù)組中。

到這里,random walk就實(shí)現(xiàn)啦!

你也可以按照其他行走方向,比如:
vector dir[] = array({0,1,0},set(-sqrt(3)/2.0,-0.5,0),set(sqrt(3)/4.0,-0.5,0.75),set(sqrt(3)/4.0,-0.5,-0.75),{0,-1,0},set(sqrt(3)/2.0,0.5,0),set(-sqrt(3)/4.0,0.5,-0.75),set(-sqrt(3)/4.0,0.5,0.75));
隨機(jī)數(shù)取值時改為rand(...) * len(dir),得到不一樣的結(jié)果,如下圖所示:

今日就分享這么多,感謝閱讀,下回見~