欢迎光临散文网 会员登陆 & 注册

Houdini学习笔记029_一个节点实现随机行走

2022-09-18 13:10 作者:独孤嘌呤  | 我要投稿

今天我们来做如下所示的random walk(随机行走)效果,全程只用到一个Attribute Wrangle节点。

下面是VEX脚本,Run Over方式选择Detail (only once)。

整体思路很简单,设定一个初始点,每步走一格。每步行走的方向在上、下、前、后、左、右中六选一。如果下一步位置已经走过,则重新选方向。

我们先从最简单的情况入手——只朝一个方向走

(一)设置初始点:

vector p0 = 0;

矢量如果只给一个数值,如0,等同于{0,0,0}。addpoint函数添加点,编号返回给整型变量npt。

(二)设定方向:

vector dir = {1,0,0};

每步行走用for循环语句实现,这里设置了两个参数,一个是总步数steps,一个是步长step length,写法如下。记得每次循环最后用新的点坐标作为下一次循环起始的点坐标,即:

p0 = p1;

(三)连点成线:

前面的笔记中已经讲过多次。每次添加点时,返回的编号nptappend函数添加到一个数组(pts[ ])中。最后用addprim函数画线:

addprim(geoself(), "polyline", pts);

第一个目标完成~

下面,我们让每一步行走的方向是随机的。

方法是先设定一个方向的数组,定义上下前后左右六个方向。

vector dir[ ] = array({1,0,0}, {-1,0,0}, {0,1,0}, {0,-1,0}, {0,0,1}, {0,0,-1});

每次循环时,从六个方向中随机选取一个,使用的是rand函数,另外可以加一个seed种子来产生变化,写法如下:

int rd = int(rand(i + chf("seed")) * 6);

随机数乘以6再取整得到的就是0、1、2、3、4、5中的任一数值,而后方向矢量取值dir[rd]即可。得到的结果如下——

随机方向是实现了,但现在的问题是,不能避免走回头路。即分岔点处走了不止一次。所以在走之前我们还要加个判断条件,确保下一个位置没走过。

我的思路是这样的,把之前走过的点的位置放在一个数组中,每走新的一步之前,将下一个目标的位置与数组中已有点位置进行比较,如果有重合,则重新选择行走的方向。判断位置是否重合可以用distance函数,如果距离小于某个很小的值,就认为两点是重合的。

比较下一个点与之前走过的点的位置也要用到for循环(每一个都要计算距离),dis如果小于0.001则认为是0,否则认为是1。每次结果相乘,如果有一个是0,那么最终结果必定是0。说明这个位置之前走过,重走!

图中红波浪线提示处 ;应在 } 里面

重走的方式也很直接,用continue跳出当前循环,直接进入下一个循环即可。如果行走成功,那么用append函数将新的点p1放进dots数组中。

到这里,random walk就实现啦!

你也可以按照其他行走方向,比如:

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));

随机数取值时改为rand(...) * len(dir),得到不一样的结果,如下图所示:

今日就分享这么多,感谢阅读,下回见~

Houdini学习笔记029_一个节点实现随机行走的评论 (共 条)

分享到微博请遵守国家法律