█世俗如此强大,让你误以为世俗就是真实的。当你被他人禁锢时,当你被世俗左右时,当你被现实打击时,你变得彷徨,迷茫和沮丧。穿越时间的长河,才能看清什么对生命是最重要的。— 每天翻译一篇教程,这就是我写给houdini的情书。【首发于同名公众号:“致houdini的情书”】
█ 时空隧道?
前言不搭后语:
年轻时想要快点成熟远离稚嫩;但当生活的压力扑面而来时,又想回到单纯快乐的时光。这时就会开始做不切实际的穿越梦。
圆方,你怎么看?
今天这节内容:
如何使用一个列表公式连线
▉今天是42岁第039天周一
这是写给houdini的
第065封“情书”
我是geo流程图
//------------构建推荐序列-----------------
int numiter = chi(“Iterations”);
int sequence[];
push(sequence,0);
//-- 4 循环— for(int n=1; n <= numiter; n++){ int a = sequence[n-1]-n; if(a>0 && find(sequence,a)<0){ } else{ a = sequence[n-1] + n; } push(sequence, a);
} i[]@sequence = sequence; |
int subdivs = chi(“Subdivisions”); int sequence[] = i[]@sequence; int prevnumber = 0; float prevdist = 0; int dir = 1; foreach(int a; sequence){ if(a>0){
float dist = a- prevnumber;
if(dist>0 && prevdist >0) dir = -1; if(dist<0 && prevdist <0) dir = -1;
float radius = dist0.5;
vector ctr = set(a-radius,0,0);
//---------使用“中心点”“半径”产生形成半圆的中间点---------- int pts[];
float angleincrement = PI / float(subdivs);
for(float angle = 0; angle <= PI; angle += angleincrement){ float x = cos(angle) radius; float y = sin(angle)* radius* dir; vector offset = set(x,y,0); // 偏移量 vector pos = ctr + offset;
int newpt = addpoint(0,pos); push(pts,newpt); } addprim(0,“polyline”,pts);
prevdist = dist; } prevnumber = a; } |
A
创建Recaman序列
两个判断条件求正确的a(n)点序列
(一)两种条件:a(n)=a(n-1)-n
1)“往回跳”成立时:a(n)>0,执行a(n)公式
2)“往前跳”成立时:a(n)<0,执行a(n)=序列[n-1]+n
(二)把a放入列表sequence:push(sequence, a)
(三)把序列放入列表属性i[]@sequence = sequence
B
将序列点连接成圆弧线条
1 引入 prevnumber prevdist
2 同方向跳跃两次作为判断条件创建翻转弧度变量dir
3 画出半圆圆弧
a)变量: 1)点数列表int pts[];2)角度增量变量angleincrement = PI / float(subdivs);
b)for循环在180度内,逐步增加角度增量,结合余弦正弦画出点位置:1)float x = cos(angle)* radius;2)float y = sin(angle)* radius* dir;3)偏移vector offset = set(x,y,0);4)点位置vector pos = ctr + offset;5)增加半圆点int newpt = addpoint(0,pos);6)放入列表push(pts,newpt); 7)增加连线addprim(0,“polyline”,pts); 8)更新变量“前距离”prevdist = dist; “前数字”prevnumber = a;
原理部分
Recaman
雷卡曼
序列
起始
所有的故事都是从一条从0开始的整数数字线开始;
原理
1)根据一个逐次加一的迭代值N;每次从数字A“首先向后”跳“N个数值”到数字B。
2)判断是否成立,
a)成立(从B再向前跳N+1个数值);
b)不成立(从A向前跳N+1个数值)如此循环;
模型具体运算过程
<第一次迭代> 数字“0”
“0”的位置,迭代值n=1
1)第一次迭代值n=1
第一件事:“向后1步”,到达数字=负值【而负值不被允许】
第二件事:“向前1步”,到达数字=“1”
<第二次迭代> 数字“1”
“1”的位置,迭代值n=2
2)第二次迭代值n=2
第一件事:“向后2步”;到达数字=负值【不被允许】
第二件事:“向前2步”:到达数字=“3”
<第三次迭代> 数字“3”
来到“3”的位置。
3)第三次迭代值n=3,
第一件事, “向后3步” :得到数值=0 【0曾经访问过也不被允许】
第二件事: “向前3步” :到达数字=“6”
<第四次迭代> 数字“6”
来到“6”的位置。
4)第四次迭代值n=4,
第一件事, “向后4步” 。数值=2
第二件事: 此时迭代值n=4结束,从“2” “向前5步”到达数字“7”
<第五次迭代> 数字“2”
来到“2”的位置。
5)“2”:第五次迭代值n=5,
第一件事, “向后5步” 。数值=负值
第二件事, “向前5步” 。数值=7
<第六次迭代> 数字“7”
来到“7”的位置。
6)“7”:第六次迭代值n=6,
第一件事, “向后6步” 。数值=1(访问过,不被允许)
第二件事, “向前6步” 。数值=13
总结
结构与规律
1。当同一方向上进行两次连续跳跃后,翻转“弧度的方向”
2。所以只需要检查是否在同一方向上连续跳跃两次;然后翻转红线部分;
开始正式制作
使用软件houdini16.5
整数序列的在线百科全书网站
recaman’s 序列:oeis.org/A005132 这里归档了数字序列;以及如何它们构造 。
公式
a(0) = 0; for n > 0, a(n) = a(n-1) - n if positive and not already in the sequence, otherwise a(n) = a(n-1) + n.
1)如果是正值,并且没有出现自序列中
a(n) = a(n-1) – n,
否则otherwise
a(n) = a(n-1) + n.
1) attributwrangle1 // Run Over:Detail(only once)
a) Iteration=32
首先
—构造一个数字序列[0,1,3,6,3,7,13…]
1)选择运行一次: 设定迭代值Iteration=32
//------------构建推荐序列-----------------
//-- 1 迭代值
int numiter = chi(“Iterations”);
//-- 2 存储将要生成数字的序列
int sequence[];
//-- 3 迭代跳跃前 初始化一些条件
//-- 3a 首先 序列中的第一个数0;
push(sequence,0);
//-- 4 在迭代值内进行循环—
for(int n=1; n <= numiter; n++){
//-- 4-1 套用recaman公式
a(0) = 0; for n > 0, a(n) = a(n-1) - n if positive and not already in the sequence, otherwise a(n) = a(n-1) + n. |
int a = sequence[n-1]-n;
//-- 4-2 find函数判断a是否存在于列表中,没有找到返回-1//-------------------------“往回跳跃”
if(a>0 && find(sequence,a)<0){
(满足“往回跳跃”条件:a(n-1)>a(n)&& a不在序列中)
}
//-------------------------“往前跳跃”
else{
a = sequence[n-1] + n;
}
//-- 4-3 将a添加进列表,a就是正确的点序号
push(sequence, a);
}
//-- 5 把序列作为detail属性来写
i[]@sequence = sequence;
问题)如何画“弧线”
分析)比如从2到7这段弧线;需要知道“中心点”“半径”
2) attributwrangle1 // Run Over:Detail(only once)
//Subdivisions=64
2)通过两点之间的距离dist,可以同时找到“中心点”和“半径”
a)半径= dist/2 或 dist0.5
b)中心点=目标点-半径
c)正弦和余弦生成半圆;
//---------------------准备工作---------------------
//-- 1 细分变量
int subdivs = chi(“Subdivisions”);
//-- 2 导入detail-列表属性
int sequence[] = i[]@sequence;
//float PI = 3.1415926;
//-- 在迭代列表数字之前,之前的点已经存储的几个变量;初始化之前的数字
int prevnumber = 0;
//-- 当我们决定是否翻转一个半圆;在相同的方向走第二步时;需要存储之前跳转的距离。把它存储到prevdist中; float prevdist = 0; |
//-- 判断方向,在轴之上,还是轴之下;
int dir = 1;//另一个方向就是-1;
//----------------开始工作:迭代列表中的数值----------
//-- 每次迭代,从列表中取出一个值,写进a中
foreach(int a; sequence){
if(a>0){
//-- 先检查一下距离;
float dist = a- prevnumber;
//-- 同一方向,迈出第二步的,圆弧朝向
if(dist>0 && prevdist >0) //dist>0=当前点“向前跳”prevdist >0=前一个点“向前跳”当前圆弧在轴之上
dir = -1; //翻转
if(dist<0 && prevdist <0)
dir = -1;
//-- 半径 翻转(连续两段)
float radius = dist0.5;
//-- 标出半圆的中心
vector ctr = set(a-radius,0,0);
//---------使用“中心点”“半径”正弦余弦产生形成[半圆]的中间点----------
//---------使用三角函数形成直线
int pts[];
//-- 画出一个圆每一步的角度;角度增量,迭代值越大,细分间隔角度越小
float angleincrement = PI / float(subdivs);
//-- for循环画出这些点的坐标,迭代一个浮点角度从0开始,计算半圆上各个位置
for(float angle = 0; angle <= PI; angle += angleincrement){
//-- 确定点的位置
float x = cos(angle) radius;
float y = sin(angle) radius* dir;
vector offset = set(x,y,0); // 偏移量
vector pos = ctr + offset;
//-- 创建半圆的点
int newpt = addpoint(0,pos);
//-- 把点增加到点列表
push(pts,newpt);
}
addprim(0,“polyline”,pts);
//-- 必须更新prevdist,下一次迭代使用
prevdist = dist;
}
prevnumber = a;
}
attribwrangle1的“迭代”
attribwrangle2的“细分”
“迭代”=48;“细分”=64
“迭代”=140“细分”=64
“迭代”=48;“细分”=3
“迭代”=48;“细分”=2
今天就到这儿了,收功
教程翻译自entagma的网络教程
下一节:xx
本文图片全部原创,版权归原作者所有