HoudiniVex笔记_P13_TrigonometryBasics三角函数

2024-01-03 03:20

本文主要是介绍HoudiniVex笔记_P13_TrigonometryBasics三角函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

Houdini版本:19.5

1、度和弧度

角度的两种表达方式:度【°】和弧度【π】。
在Houdini里的大多数情况下,需要将角度转换成弧度进行计算。
π=180°≈3.14=圆周长/直径。

eg.可使用类型为detail的attributeWrangle节点验证以下代码:

float degrees = chf('degrees');
float radians = chf('radians') * PI * 2.0;;f@radians = radians(degrees);   //若degrees=180,则radians≈3.14159
f@degrees = degrees(radians);   //若radians=1,则degrees=360
f@pi= PI;                       // pi ≈ 3.14

2、π计算


3、正弦sin、余弦cos、正切tan

如下图所示,在单位为1的圆内,正弦sinθ = b,余弦cosθ = c,正切tanθ = b/c,

4、三角函数可视化

eg.①首先搞条z轴旋转45°的直线/Transform节点的旋转z轴(方便理解)

②以这条线为直角三角形的斜边,创建另外两条边,并设置detail属性,分别在PointWrangle中输入代码

//PointWrangle节点hline    
if(@ptnum == 1){@P.y = 0.0;setdetailattrib(0, 'c', @P.x);
}
//PointWrangle节点vline
if(@ptnum == 0){vector npos = point(0, 'P', 1);@P.x = npos.x;
}if(@ptnum == 1){setdetailattrib(0, 'b', @P.y);
}

③合并三条边之前,先用测量节点measure确定斜边的长,以及用attribpromote节点把斜边长度转为detail属性

④三边合并,并添加一个以斜边为半径的圆合并:
其中圆的半径引用斜边的长度【复制—粘贴参数引用】,

 ⑤最后在,mergre下添加一个类型为detail的AttributeWrangle节点,写入以下代码:

float rad = chf('rad');             //自定义半径
float ang = radians(chf('ang'));    //自定义角度float a = f@a;  //高度
float b = f@b;  //宽度
float c = f@c;  //斜边f@sinval = b/a;
f@cosval = c/a;
f@tanval = b/c;f@sinval2 = sin(ang);
f@cosval2 = cos(ang);
f@tanvla2 = tan(ang);f@b2 = sin(ang) * a;
f@c2 = cos(ang) * a;

 其中,自定义半径<——斜线【复制—粘贴参数引用】、自定义角度<——Transform节点的旋转z轴【复制—粘贴参数引用】,

结果:略

5、练习1——画圈圈

 eg.利用sin、cos函数画圈圈。在类型为detail的attributeWrangle节点写入以下代码

int num = chi('num');
float rad = chf('rad');for(int i =0; i<num; i++){float ang = 2.0 * $PI / num * i;    //角度递增,最大为360°float x = cos(ang) * rad;float y = sin(ang) * rad;vector pos = set(x, y, 0);int pt = addpoint(0, pos);
}    //结果如下:

6、练习2——画转圈圈

先上结果:小球从最左点开始绕圈圈运动。

操作:
类型为Points的AttributeWrangle节点(命名为oribt)写入以下代码: 

float ang = radians(chf('ang'));    //角度、范围设为0~360
float rad = chf('rad');             //半径、大小随意float x = cos(ang) * rad;       //x坐标
float y = sin(ang) * rad;       //y坐标@P = set(x, y, 0);

其它设置:add节点(添加1个点)、sphere节点(polygon、缩小)、circle3节点的缩放<——oribt节点的半径通道rad【复制—粘贴参数引用】、oribt节点的角度通道Ang写成【$FF / $FEND * 360】

7、练习3——画大波浪

大概就是利用三角函数画出它们的坐标图。

eg.在类型为detail的attributeWrangle节点写入以下代码:

int num = chi('num');
int switch = chi('switch');   //根据输入的数字,切换不同三角函数计算方式for(int i=0; i<num; i++){float ang = $PI * 2.0 *i / num * chf('wavenum');    //起伏幅度次数,即角度大小float x = ang;float y = 0.0;if(switch == 0){y = sin(ang);}else if(switch == 1){y = cos(ang);}else if(switch == 2){y = tan(ang);}vector pos = set(x, y, 0.0);int pt = addpoint(0, pos);
}

 结果大概是类似下面这种样子:

8、练习4——沿着大波浪动

eg.如下图添加节点,其中add节点(添加一个点)、animate_wave节点(points类型)

 在animate_wave中输入以下代码:

float ang = radians(chf('ang'));    //设置范围0~360float x = ang;        //若x=0,小球将上下运动
float y = sin(ang);@P = set(x, y, 0);

其中,在通道角度ang中输入【$FF / $FEND * 360 * 2.0】(2.0为自定义倍速)
结果为:小球运动规律符合sin函数规律。

9、三角函数值范围

如下图所示,图片来自@门酱胡安,图一为sin、cos函数图像,第二章为tan函数图像。

如若不懂,可以结合【3、正弦sin、余弦cos、正切tan】的图像去理解。

10、练习5——动态缩放

eg.Sphere小球节点(polygon)、PointWrangle节点,并写入以下代码:

float val = cos($PI * 2.0 * @Frame / $FEND * 2);    // *2仅是让小球缩放快些val = fit(val, -1.0, 1.0, 0.1, 1.0);    //映射函数,把val值(-1.0, 1.0),映射到(0.1, 1.0)@P *= val;

结果:小球缩放规律类似cos函数

11、反三角函数

这里大概看看就好,深入了解可以看这篇文章的推导过程。

常用的另外三个三角函数:
cot余切=1/正切=邻边/对边,
sec正割=1/余弦=斜边/邻边,
csc余割=1/正弦=斜边/对边。

反三角函数:反正弦arcsin、反余弦arccos、反正切arctanx。可以理解为将原三角函数的x、y调换位置所得,如图所示,

 反函数的导数等于直接函数的导数的倒数:

 eg、可以在类型为detail的attributeWrangle节点写入以下代码,并结合前面代码验证另外三个三角函数结果:

//余割、余切、正割
float ang = radians(chf('ang'));f@cosecant = 1.0 / sin(ang);
f@secant = 1.0 / cos(ang);
f@cotangent = 1.0 / tan(ang);

12、使用反三角函数获取角度

使用反三角函数估算角度,多少有点不完美,使用 atan2() 函数完美解决。

eg.直接使用【4、三角函数可视化】的案例,仅对最后的attributeWrangle节点的代码进行修改,

float rad = chf('rad');             //自定义半径
float ang = radians(chf('ang'));    //自定义角度float a = f@a;  //高度
float b = f@b;  //宽度
float c = f@c;  //斜边f@sinval = b/a;
f@cosval = c/a;
f@tanval = b/c;f@sineang = degrees(asin(f@sinval));    //当角度位于180°~270°~360°时,得到的角度值从0°开始到-90°再到0°
f@cosang = degrees(acos(f@cosval));     //当角度位于180°~270°~360°时,得到的角度值为180°~0°
f@tanang = degrees(atan(f@tanval));     //当角度位于90°~270°、270°~360°时,得到的角度值为-90°~90°,-90°~0°//用Houdini自带的atan2()函数完美解决角度估算问题
// atan2() 函数仅需要x、y值(两条直角边)
f@tanang2 = degrees(atan2(b, c));      

结果:略

13、练习6——两向量角度

理论:如下图所示,求向量A、B的夹角角度。
①对向量A进行归一化,利用点积求得边长a的值;
②勾股定理,a²+b²=c²,求得b值(c²=x²+y²+z²);
③反函数atan2()求得角度θ。

eg.按下图设置创建两条直线,通道参数可直接拖拽创建:通道与直线的旋转【复制—粘贴参数引用】,当然也可以对直线直接设定恒定旋转值,以验证结果。

 在angle_arc输入以下代码:

//根据直线首末两个顶点坐标,获取向量值
int pts1[] = primpoints(0, 0);
int pt11 = pts1[0];
int pt12 = pts1[1];
vector pos11 = point(0, 'P', pt11);
vector pos12 = point(0, 'P', pt12);
vector dir1 = pos12 - pos11;           //根据直线首末两个顶点坐标,获取向量值
int pts2[] = primpoints(0, 1);
int pt21 = pts2[0];
int pt22 = pts2[1];
vector pos21 = point(0, 'P', pt21);
vector pos22 = point(0, 'P', pt22);
vector dir2 = pos22 - pos21;float dot = dot(normalize(dir1), dir2);     //根据点积,求得a值
float vlen = length(dir2);                  //向量B的长度
float h = sqrt(pow(vlen, 2) - pow(dot, 2)); //勾股定理,求得b值float ang = atan2(h, dot);                  //反三角函数,求得角度f@ang = degrees(ang);                       //两个向量之间的夹角

结果:略

14、练习——两向量之间画弧

理论:①根据叉乘,可以得到两个向量的垂直向量,即法线向量,暂且将其定为(虚假的)Z轴;
②把其中一个向量作为(虚假)的X轴,与Z轴求得(虚假的)Y轴;
③(虚假)X、(虚假)Y轴所构成的平面就是两个向量之间构成的平面;用三角函数sin、cos即可求得生成点在(虚假)X轴、(虚假)Y轴上的坐标。

直接使用【13、Exercise练习6——两向量角度】的项目,对代码进行修改为,

//根据直线首末两个顶点坐标,获取向量值
int pts1[] = primpoints(0, 0);
int pt11 = pts1[0];
int pt12 = pts1[1];
vector pos11 = point(0, 'P', pt11);
vector pos12 = point(0, 'P', pt12);
vector dir1 = pos12 - pos11;           //根据直线首末两个顶点坐标,获取向量值
int pts2[] = primpoints(0, 1);
int pt21 = pts2[0];
int pt22 = pts2[1];
vector pos21 = point(0, 'P', pt21);
vector pos22 = point(0, 'P', pt22);
vector dir2 = pos22 - pos21;float dot = dot(normalize(dir1), dir2);     //根据点积,求得a值
float vlen = length(dir2);                  //向量B的长度
float h = sqrt(pow(vlen, 2) - pow(dot, 2)); //勾股定理,求得b值float ang = atan2(h, dot);                  //反三角函数,求得角度f@ang = degrees(ang);                       //两个向量之间的夹角//上面代码与前面相同//画弧
vector xaxis = normalize(dir1);             //其中之一的向量归一化,虚假的X轴
vector zaxis = normalize(cross(xaxis, normalize(dir2)));    //两个向量的垂直向量,即法线向量,虚假的Z轴
vector yaxis = normalize(cross(zaxis, xaxis));              //虚假的Y轴int num = chi('num');
for(int i=0; i<num; i++){float sang = ang * i / (num - 1.0);             //对两个向量之间的夹角进行细分float x = cos(sang);                    //生成点的宽度,即直角三角形的宽度边float y = sin(sang);                    //生成点的高度,即直角三角形的高度边vector tx = xaxis * x;                  //生成点在(虚假X轴)方向的宽度/坐标vector ty = yaxis * y;                  //生成点在(虚假Y轴)方向的高度/坐标//为什么没Z轴?因为我们是以(假)X轴和(假)Y轴为平面,生成弧度点vector tpos = tx + ty;                  // "X"、"Y"轴的坐标相加,得到具体位置int pt = addpoint(0, tpos);
}

结果大概是这个样子:

这篇关于HoudiniVex笔记_P13_TrigonometryBasics三角函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/564438

相关文章

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

查看提交历史 —— Git 学习笔记 11

查看提交历史 查看提交历史 不带任何选项的git log-p选项--stat 选项--pretty=oneline选项--pretty=format选项git log常用选项列表参考资料 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的 工具是 git log 命令。 接下来的例子会用一个用于演示的 simplegit

记录每次更新到仓库 —— Git 学习笔记 10

记录每次更新到仓库 文章目录 文件的状态三个区域检查当前文件状态跟踪新文件取消跟踪(un-tracking)文件重新跟踪(re-tracking)文件暂存已修改文件忽略某些文件查看已暂存和未暂存的修改提交更新跳过暂存区删除文件移动文件参考资料 咱们接着很多天以前的 取得Git仓库 这篇文章继续说。 文件的状态 不管是通过哪种方法,现在我们已经有了一个仓库,并从这个仓

忽略某些文件 —— Git 学习笔记 05

忽略某些文件 忽略某些文件 通过.gitignore文件其他规则源如何选择规则源参考资料 对于某些文件,我们不希望把它们纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。通常它们都是些自动生成的文件,比如日志文件、编译过程中创建的临时文件等。 通过.gitignore文件 假设我们要忽略 lib.a 文件,那我们可以在 lib.a 所在目录下创建一个名为 .gi

取得 Git 仓库 —— Git 学习笔记 04

取得 Git 仓库 —— Git 学习笔记 04 我认为, Git 的学习分为两大块:一是工作区、索引、本地版本库之间的交互;二是本地版本库和远程版本库之间的交互。第一块是基础,第二块是难点。 下面,我们就围绕着第一部分内容来学习,先不考虑远程仓库,只考虑本地仓库。 怎样取得项目的 Git 仓库? 有两种取得 Git 项目仓库的方法。第一种是在本地创建一个新的仓库,第二种是把其他地方的某个

Git 的特点—— Git 学习笔记 02

文章目录 Git 简史Git 的特点直接记录快照,而非差异比较近乎所有操作都是本地执行保证完整性一般只添加数据 参考资料 Git 简史 众所周知,Linux 内核开源项目有着为数众多的参与者。这么多人在世界各地为 Linux 编写代码,那Linux 的代码是如何管理的呢?事实是在 2002 年以前,世界各地的开发者把源代码通过 diff 的方式发给 Linus,然后由 Linus