HoudiniVex笔记_P26_RecursionBasics递归基础

news2024/9/25 21:24:50

原视频: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~120

for(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;  //  switch

float 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.coloradmin.cn/o/934900.html

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

相关文章

HTML总结2 [转]

以下转载和参考自&#xff1a;HTML 表单。 1、表格 可以通过 CSS 设置表格的样式&#xff1a; 如下为将上面table.lamp th,td样式中的padding注释掉&#xff0c;开启table.lamp中的padding的效果&#xff1a; 2、列表 3、表单 表单用于收集用户的输入&#xff0c;如下图所…

【⑬MySQL | 数据类型(一)】简介 | 整数 | 浮点 | 定点 | 时间/日期类型

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL数据类型简介 | 整数 | 浮点 | 定点 | 时间/日期类型的分享✨ 目录 前言0.数据类型简介1 整数类型2 浮点类型3 定点类型4 日期/时间类型总结 0.数据类型简介 数据类型&#xff08;data_type&#xff09;是指系…

《C和指针》笔记11: external和internal链接属性

当组成一个程序的各个源文件分别被编译之后&#xff0c;所有的目标文件以及那些从一个或多个函数库中引用的函数链接在一起&#xff0c;形成可执行程序。然而&#xff0c;如果相同的标识符出现在几个不同的源文件中时&#xff0c;它们是像Pascal那样表示同一个实体&#xff1f;…

专业设计必备:Zeplin for Mac免费下载,打造独具特色的作品

Zeplin是一款高效制图软件&#xff0c;可以帮助用户更好的设计及制作图片&#xff0c;为用户提供了标注、Style Guide、备注文档与简单的团队协作功能&#xff0c;还可以自动生成尺码标注、CSS 样式代码、导出图片等。 功能介绍 量身定制的资源&#xff0c;在一个位置 Zepli…

Rabbitmq的Shovel

Federation 具备的数据转发功能类似&#xff0c; Shovel 够可靠、持续地从一个 Broker 中的队列 ( 作为源端&#xff0c;即source)拉取数据并转发至另一个 Broker 中的交换器 ( 作为目的端&#xff0c;即 destination) 。作为源端的队列和作为目的端的交换器可以同时位于…

Python通过matplotlib动态绘图实现中美GDP历年对比趋势动图

随着中国的各种实力的提高&#xff0c;经常在各种媒体上看到中国与各个国家历年的各种指标数据的对比&#xff0c;为了更清楚的展示历年的发展趋势&#xff0c;有的还做成了动图&#xff0c;看到中国各种指标数据的近年的不断逆袭&#xff0c;心中的自豪感油然而生。今天通过Py…

2023.8.27 碎碎念

碎碎念系列更新 离上次更新快一个月了 随便写写 一、关于工作 公司项目应用端开发&#xff08;了解了shell&#xff0c;awk等&#xff09;公司自研APP维护 后续计划写一篇shell相关的博客 二、关于学习 最近把算法也捡起来了&#xff0c;虽然还是很菜&#xff0c;今天周赛…

回归预测 | MATLAB实现GWO-ELM灰狼算法优化极限学习机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现GWO-ELM灰狼算法优化极限学习机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现GWO-ELM灰狼算法优化极限学习机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一览基本介绍程…

单片机电子元器件-数码管

数码管分类 共阳 把所有数码管的阳极接到一起形成公共阳极COM 数码管 共阳极COM 接到 5V 电源 共阴 把所有数码管的阴极接到一起形成公共阴极COM 数码管 共阴极COM 接到 地 GND 上 八段 数码管 和 七段数码管&#xff0c; 多了一个 小数点 DP 数码管显示原理 一个数码管如…

YOLO目标检测——肺炎分类数据集下载分享

肺炎分类数据集总共21000图片&#xff0c;可应用于&#xff1a;肺炎检测、疾病诊断、疾病预测和预警等等。 数据集点击下载&#xff1a;YOLO肺炎分类数据集21000图片.rar

Fooocus启动时modules报错的解决方法

原理&#xff1a;是由于其他程序的安装导致modules的版本不对&#xff0c;先卸载现有版本&#xff0c;再运行run.bat让其自动安装响应的modules版本。 1、cmd运行windows dos终端。 2、将Fooocus_win64_1-1-1035文件夹备份&#xff0c;rename为Fooocus_win64_1-1-1035backup文…

轻松上传、管理和分享图片——PicGo for Mac,你的最佳选择

作为一名经常使用图片的用户&#xff0c;你一定经历过图片上传、管理和分享的烦恼。PicGo for Mac是一款专为Mac用户设计的图片上传工具&#xff0c;它能够帮助你轻松完成这些任务。 首先&#xff0c;PicGo for Mac提供了一种简单而高效的方式来上传图片。你只需将图片拖放到Pi…

《网络是怎样连接的》(五)

本文主要取材于 《网络是怎样连接的》 第五章。 目录 5.1 Web服务器的部署地点 5.2 防火墙的结构和原理 5.3服务器负载平衡 5.4 使用缓存服务器分担负载 5.5 内容分发服务 简述&#xff1a;本文主要内容是解释 网络包如何朝服务器前进&#xff0c;并通过服务器前面的防…

VM——西门子Smart 200进行S7通信

1、参考文章《海康VisionMaster与西门子Smart 200进行S7通信_机器人自动化控制的博客-CSDN博客》 2、注意事项&#xff1a; &#xff08;1&#xff09;PLC设置的变量类型是VW&#xff0c;而不是MW。 &#xff08;2&#xff09;与S7一样&#xff0c;默认端口号是102&#xff…

深入剖析Kubernetes之控制器模式的实现-Deployment

文章目录 Deployment Deployment Deployment 实现了 Kubernetes 项目中一个非常重要的功能&#xff1a;Pod 的“水平扩展 / 收缩”&#xff08;horizontal scaling out/in&#xff09;。这个功能&#xff0c;是从 PaaS 时代开始&#xff0c;一个平台级项目就必须具备的编排能力…

在Windows操作系统上安装Neo4j数据库

在Windows操作系统上安装Neo4j数据库 一、在Windows操作系统上安装Neo4j数据库 一、在Windows操作系统上安装Neo4j数据库 点击 MySQL可跳转至MySQL的官方下载地址。 在VUE3项目的工程目录中&#xff0c;通过以下命令可生成node_modules文件夹。 npm install&#xff08;1&am…

用U盘装Ubuntu22.04双系统前需要提前规避的两大问题

如果你是GPT分区&#xff0c;且Bios开启了UEFI&#xff08;无论你选的是启动模式是LegacyUEFI还是UEFI&#xff0c;都算开启了UEFI&#xff09;那你装Ubuntu时可以忽略本文&#xff0c;只看最末尾的装机教程 以下2个问题叠加&#xff0c;就会出现引导丢失的问题&#xff08;版…

【持续更新中】QAGroup1

OVERVIEW Q&AGroup1一、语言基础1.C语言&#xff08;1&#xff09;含参数的宏与函数的不同点&#xff08;2&#xff09;sizeof与strlen的区别&#xff08;3&#xff09;大/小端&#xff08;4&#xff09;strcpy与memcpy的区别&#xff08;5&#xff09;extern与static的区别…

代码随想录算法训练营之JAVA|第三十九天|474. 一和零

今天是第39天刷leetcode&#xff0c;立个flag&#xff0c;打卡60天。 算法挑战链接 474. 一和零https://leetcode.cn/problems/ones-and-zeroes/ 第一想法 题目理解&#xff1a;找到符合条件的子集&#xff0c;这又是一个组合的问题。 看到这个题目的时候&#xff0c;我好像…

软件测试报告包含哪些内容?

软件测试报告一般包含以下内容&#xff1a; 1、引言&#xff08;目的、背景、缩略语、参考文献&#xff09; 2、测试概述&#xff08;测试目的、项目介绍、测试目标&#xff09; 3、测试资源&#xff08;测试人员、测试软硬件环境及配置、测试环境的网络拓扑&#xff09; 4…