HoudiniVex笔记_P26_RecursionBasics递归基础

原视频:https://www.youtube.com/playlist?list=PLzRzqTjuGIDhiXsP0hN3qBxAZ6lkVfGDI
Bili:Houdini最强VEX算法教程 - VEX for Algorithmic Design_哔哩哔哩_bilibili

Houdini版本:19.5

1、概述

递归是一种直接或者间接地调用自身的算法,一般计算机中的递归算法实现不适用于Houdini的Vex(通过函数或子过程来完成)。详情可见后面谢尔宾斯基三角的例子。

图片来自@bky2016的文章,感兴趣可以去看看。

本章主要使用以下几种方式实现递归:
A)、For-Each节点,
B)、For-Each节点 + VEX
C)、Solver解算器
D)、纯VEX(复杂),

提前剧透:B、C两种方法计算最快

关于For-each节点,可以看这知乎@ZeTii的Houdini 中for-each 和for-loop 节点文章。

2、螺旋线与回归

用上面的四种方法分别实现一根螺旋线,

①节点连接及设置如下,(代码节点的通道值自行设置),


②补充,节点代码如下, 

//  B——sprial_recursively节点代码float steplenx = chf('steplenx');
float stepleny = chf('stepleny');
float stepang = chf('stepang');vector pos = @P;pos = pos + v@dir * steplenx;       // pos沿X位移matrix mat = ident();
rotate(mat, radians(stepang), set(0,1,0));
pos *= mat;pos += set(0,1,0) * stepleny;     // pos沿Y位移,即高度int newpoint = addpoint(0, pos);setpointattrib(0, 'dir', newpoint, v@dir);  
//盲猜在For-Each循环内,除了第一次,其它循环不能访问外部属性setpointgroup(0, 'last', newpoint, 1);
setpointgroup(0, 'last', @ptnum, 0);
//  C——解算器Solver内代码//与上面一样
//  D——sprial_recursively1节点代码vector pos = @P;for(int i=0; i<chi('numite'); i++){float steplenx = chf('steplenx');float stepleny = chf('stepleny');float stepang = chf('stepang');pos = pos + v@dir * steplenx;       // pos沿X位移matrix mat = ident();rotate(mat, radians(stepang), set(0,1,0));pos *= mat;pos += set(0,10) * stepleny;     // pos沿Y位移,即高度int newpoint = addpoint(0, pos);//属性设置不用啦,可以直接访问了
}

3、谢尔宾斯基三角与递归

谢尔宾斯基三角形是这样子的,

本节主要用下面的方法实现谢尔宾斯基三角,(当然,也有其它方法),
For-Each实现方法,

其它三种实现原理大概如下,

①节点连接及设置如下,

 ②补充,节点代码如下,

//  B——sierpinski_triangle节点代码int pts[] = primpoints(0, @primnum);for(int i=0; i<len(pts); i++){int pt = pts[i];vector pos = point(0, 'P', pt);int triprim = addprim(0, 'poly');for(int n=0; n<len(pts); n++){int npt = pts[n];vector npos = point(0, 'P', npt);npos -= pos;npos *= 0.5;npos += pos;int newpoint = addpoint(0, npos);addvertex(0, triprim, newpoint);}
}removeprim(0, @primnum, 1);
//  C——解算器Solver内代码//与上面一样
//  D——sierpinski_triangle1节点内代码int pts[] = primpoints(0, @primnum);
vector positions[] = array();
for(int  i=0; i<len(pts); i++){vector pos = point(0, 'P', pts[i]);append(positions, pos);
}for(int t=0; t<chi('numite'); t++){int numtri = len(positions) / 3;vector newpositions[] = array();for(int s=0; s<numtri; s++){for(int i=0; i<3; i++){vector pos = positions[s * 3 + i];for(int n=0; n<3; n++){vector npos = positions[s * 3 + n];npos -= pos;npos *= 0.5;npos += pos;append(newpositions, npos);}}}positions = newpositions;
}removeprim(0, @primnum, 1);int numtri = len(positions) / 3;
for(int s=0; s<numtri; s++){int tri = addprim(0, 'poly');for(int i=0; i<3; i++){vector pos = positions[s * 3 + i];int npt = addpoint(0, pos);addvertex(0, tri, npt);}
}

4、性能测试:谢尔宾斯基三角

性能测试点这里,不懂去看视频(1h45min)。

结果: 谢尔宾斯基三角11次迭代花费时间

5、2D L-系统树与递归

分叉分形,为下一节的3D树打基础,老规矩先上结果,

eg.①节点设置及连接如下, 

②补充,pointwrangle1节点代码如下,

float branchang = radians(chf('branchang'));    //范围设 0~120for(int i=0; i<3; i++){float a = -branchang + i * branchang + f@ang;   //妙鸭 三个角度vector dir = set(1,0,0);matrix mat = ident();rotate(mat, a, set(0,1,0));dir *= mat;vector newpos = @P + dir * f@len;int newpt = addpoint(0, newpos);int line = addprim(0, 'polyline', @ptnum, newpt);//设置属性以便访问setpointgroup(0, 'end', newpt, 1);setpointattrib(0, 'len', newpt, f@len * 0.5);  //长度每次变短setpointattrib(0, 'ang', newpt, a);   
}setpointgroup(0, 'end', @ptnum, 0);

6、3D L-系统树与递归

大概是使用下面这种方法实现的,

eg.①先上结果:(加各种随机参数、角度等等) ,

②节点连接及设置为,

③ 类型为Primitives的branching_tree节点Group设为:last,完整代码为,(上面两个代码一样),

float branchang = radians(f@ang);  // 分叉角度
float lenratio = chf('lenratio');  // 长度比例
float angratio = chf('angratio');  // 角度比例float minlen = chf('minlen');   // 最小长度int div = chi('div');   float seed = chf('seed');int pts[] = primpoints(0, @primnum);
int pt1 = pts[0];
int pt2 = pts[1];
vector pos1 = point(0, 'P', pt1);
vector pos2 = point(0, 'P', pt2);
vector vaxis = normalize(pos2 - pos1);  //水平轴
vector haxis = v@haxis;                 //垂直轴
float len = distance(pos1, pos2);
float thickness = point(0, 'thickness', pt2);if(len < minlen){return;
}float range = radians(chf('random_h_ang'));
float randang = rand(seed * @primnum + 33.5);
randang = fit01(randang, -range, range);matrix mat = ident();
rotate(mat, branchang + randang, haxis);vector npos = pos2;
npos -= pos1;
npos *= mat;
npos *= lenratio;for(int i=0; i<div; i++){vector npos2 = npos;float vang = $PI * 2.0 / div * i;float range2 = radians(chf('random_v_ang'));float randang2 = rand(seed * @primnum + 45.5 + i * 50.83);randang2 = fit01(randang2, -range2, range2);matrix mat2 = ident();rotate(mat2, vang + randang2, vaxis);npos2 *= mat2;npos2 += pos2;vector newhaxis = haxis;newhaxis *= mat2;int newpt = addpoint(0, npos2);setpointattrib(0, 'thickness', newpt, thickness * lenratio);int newline = addprim(0, 'polyline', pt2, newpt);setprimgroup(0, 'last', newline, 1);setprimattrib(0, 'haxis', newline, haxis);setprimattrib(0, 'ang', newline, degrees(branchang * angratio));
}setprimgroup(0, 'last', @primnum, 0);

7、矩形细分与递归

摆烂,但还是记录下,毕竟最后一个了。

本次实现下面这种细分,

eg.①最终结果,

②节点连接及设置,

③ 类型为Primitives的sq_subdivision节点代码为,

int ite = detail(1, 'iteration');
int pts[] = primpoints(0, @primnum);int sw = 1 - i@sw;  //  switchfloat seed = chf('seed') + ite * 43.2 +@primnum * 4.6;
float randval = rand(seed);
float minscale = chf('minscale');
randval = fit01(randval, minscale, 1.0 - minscale);
randval += fit01(noise(seed + @Frame* chf('speed')), -minscale, minscale);for(int i=0; i<2; i++){int newprim = addprim(0, 'poly');setprimattrib(0, 'sw', newprim, sw);for(int n=0; n<len(pts); n++){int pt = pts[n];vector pos = point(0, 'P', pt);vector opos = point(0, 'P', pts[0]);    //第一个点vector mpos = point(0, 'P', pts[2]);    //第二个点,对角线的点vector odir = pos - opos;vector mdir = pos - mpos;vector dir = set(0,0,0);vector cpos = set(0,0,0);if(sw == 0){if(i == 0){odir.x = odir.x * randval;dir = odir;cpos = opos;}else{mdir.x = mdir.x * (1.0 - randval);dir = mdir;cpos = mpos;}}else{if(i == 1){odir.z = odir.z * randval;dir = odir;cpos = opos;}else{mdir.z = mdir.z * (1.0 - randval);dir = mdir;cpos = mpos;}}vector newpos = cpos + dir;int newpt = addpoint(0, newpos);addvertex(0, newprim, newpt);}
}removeprim(0, @primnum, 1);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/54726.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

猜数游戏-Rust版

cargo new guessing_game 创建项目 输入任意内容&#xff0c;并打印出来 main.rs: use std::io; // 像String这些类型都在预先导入的prelude里&#xff0c;如果要使用的不在prelude里&#xff0c;则需要显式导入fn main() { println!("猜数"); println!("…

37、springboot 为 spring mvc 提供的自动配置及对自动配置的一些自定义定制(大体思路)

springboot 为 spring mvc 提供的自动配置及对自动配置的一些自定义定制&#xff08;大体思路&#xff09; ★ Spring Boot主流支持两个MVC框架&#xff1a; Spring MVC&#xff08;基于Servlet&#xff09; Spring WebFlux&#xff08;基于Reactive&#xff0c;属于响应式AP…

vcomp140.dll丢失的修复方法分享,电脑提示vcomp140.dll丢失修复方法

今天&#xff0c;我的电脑出现了一个奇怪的问题&#xff0c;打开某些程序时总是提示“找不到vcomp140.dll文件”。这个问题让我非常头疼&#xff0c;因为我无法正常使用电脑上的一些重要软件。为了解决这个问题&#xff0c;我在网上查找了很多资料&#xff0c;并尝试了多种方法…

使用Aircrack-ng进行无线网络破解

Aircrack-ng是一款流行的无线网络渗透测试工具&#xff0c;主要用于密码破解和网络分析。但是&#xff0c;请注意&#xff0c;仅在有合法授权的情况下使用这些工具。 以下是一个使用Aircrack-ng进行无线网络破解的示例&#xff0c;以及一些步骤和注意事项&#xff1a; 步骤&a…

2023年最新版Windows环境下|Java8(jdk1.8)安装教程

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【JavaSE_primary】 jdk1.8的下载和使用总共分为3个步骤&#xff1a; jdk1.8的下载、jdk1.8的安装、配置环境变量。 目录 一、jdk1.8下载…

IDEA常用配置之类Tab页多行显示

文章目录 IDEA常用配置之类Tab页多行显示 IDEA常用配置之类Tab页多行显示 默认在Idea中打开类过多&#xff0c;后面会隐藏显示&#xff0c;这里修改配置&#xff0c;将类设置为多行显示&#xff0c;方便查找已经打开的类 修改后显示样式

Unity——后期处理举例

Post Processing&#xff08;后期处理&#xff09;并不属于特效&#xff0c;但现代的特效表现离不开后期处理的支持。本文以眩光&#xff08;Bloom&#xff09;为例&#xff0c;展示一种明亮的激光的制作方法 1、安装后期处理扩展包 较新的Unity版本已经内置了新版的后期处理扩…

创建型模式-建造者模式

使用多个简单的对象一步一步构建成一个复杂的对象 主要解决&#xff1a;主要解决在软件系统中&#xff0c;有时候面临着"一个复杂对象"的创建工作&#xff0c;其通常由各个部分的子对象用一定的算法构成&#xff1b;由于需求的变化&#xff0c;这个复杂对象的各个部…

ARM DIY(三)板载串口和 LCD 调试

前言 今天焊接两大关键输入输出设备&#xff1a;串口和屏幕。 串口 串口部分使用 CP2102N 芯片&#xff08;USB 转 TTL&#xff09;&#xff0c;这样用一根数据线连接板子和 PC 就可以直接调试了。 焊接 CP2102 和 Type C 上电调试&#xff0c;串口可以正常输入输出。 看来…

使用Python写入数据到Excel:实战指南

在数据科学领域&#xff0c;Excel是一种广泛使用的电子表格工具&#xff0c;可以方便地进行数据管理和分析。然而&#xff0c;当数据规模较大或需要自动化处理时&#xff0c;手动操作Excel可能会变得繁琐。此时&#xff0c;使用Python编写程序将数据写入Excel文件是一个高效且便…

【办公类-16-01-02】2023年度上学期“机动班下午代班的排班表——跳过周三、节日和周末”(python 排班表系列)

背景需求&#xff1a; 2023年第一学期&#xff08;2023年9-2024年1月&#xff09;&#xff0c;我又被安排为“机动班”&#xff0c;根据新学期的校历&#xff0c;手动推算本学期的机动班的带班表 排版原则 1、班级数量&#xff1a;共有6个班级&#xff0c;循环滚动 2、每周次…

安装启动yolo5教程

目录 一、下载yolo5项目 二、安装miniconda&#xff08;建议不要安装在C盘&#xff09; 三、安装CUDA 四、安装pytorch 五、修改配置参数 六、修改电脑参数 七、启动项目 博主硬件&#xff1a; Windows 10 家庭中文版 一、下载yolo5项目 GitHub - ultralytics/yolov5:…

使用EF Core更新与修改生产数据库

使用EF Core的Code First&#xff0c;在设计阶段&#xff0c;直接使用Database.EnsureCreated()和EnsureDeleted()可以快速删除、更新最新的数据结构。由于没有什么数据&#xff0c;删除的风险非常低。但是对于已经投入生产的数据库&#xff0c;这个方法就绝对不可行了。 考虑…

【C进阶】指针(一)

大家好&#xff0c;我是深鱼~ 【前言】&#xff1a; 指针的主题&#xff0c;在初阶指针章节已经接触过了&#xff0c;我们知道了指针的概念&#xff1a; 1.指针就是个变量&#xff0c;用来存放地址&#xff0c;地址的唯一标识一块内存空间&#xff08;指针变量&#xff09;&a…

集丰照明|汽车美容店设计,装修色彩灯光搭配方法

正确处理好店面的空间设计。 店铺各个功能区设计要合理&#xff0c;衔接合理&#xff0c;这样既能提高员工的工作效率也能提高顾客的满意度。合理安排店铺的空间分配&#xff0c; 要给顾客一种舒适度&#xff0c;既不能让顾客感觉到过于拥挤&#xff0c;又不能浪费店铺的有限空…

.NET Core 实现日志打印输出在控制台应用程序中

在本文中&#xff0c;我们将探讨如何在 .NET Core 应用程序中将日志消息输出到控制台&#xff0c;从而更好地了解应用程序的运行状况。 .NET Core 实现日志打印输出在控制台应用程序中 在 .NET Core 中&#xff0c;日志输出打印是使用 Microsoft.Extensions.Logging 命名空间…

【LeetCode-面试经典150题-day14】

目录 19.删除链表的倒数第N个结点 82.删除排序链表中的重复元素Ⅱ 61. 旋转链表 86.分隔链表 146.LRU缓存 19.删除链表的倒数第N个结点 题意&#xff1a; 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 【输入样例】head [1,2,3,4,5…

element-ui里el-table表格操作列多横线怎么解决

错误展示 错误原因 在vue中封装了element-ui表格&#xff0c;然后使用插槽&#xff0c;fixed定位等&#xff0c;导致样式出现了错乱 解决方案 1、线没有对齐 /* Element-UI 的table 组件出现表格线条不对齐的问题 */ body .el-table th.gutter {display: table-cell !impor…

基于MATLAB开发AUTOSAR软件应用层Code mapping专题-part 5 Signal/States标签页介绍

这一篇我们说下signals和State这两个怎么搞做映射,那首先我们要知道什么是Signal和state,我们看下模型, 在原来的模型里我增加了标红的圆圈处delay模块,这个delay模块就是一个state模块,表示离散的一个状态,这个是个模型的基本概念,后续我有个专栏交接simulink建模,那…

专题:平面、空间直线参数方程下的切线斜率问题

本文研究平面、空间直线在参数方程形式下&#xff0c;切线斜率&#xff08;即导数&#xff09;如何表示的问题。 如上图所示。 设 y f ( x ) &#xff0c; x φ ( t ) &#xff0c; y ψ ( t ) 当 t t 0 时&#xff0c; x x 0 &#xff0c; y y 0 &#xff0c;即点 A 坐…