Turtle(L_Systems)语言入门指南
Turtle龟语言,一种L_Systems语言,是c4dr12中加入的新功能中的一个重点,这种语言并不复杂,所有的指令都围绕着一个F展开,就像一个爬行中的小龟,我们通过各种指令来控制小龟的爬行路径,最后用路径来描绘我们期望的图形。
Turtle龟语言,一种L_Systems语言,是c4dr12中加入的新功能中的一个重点,这种语言并不复杂,所有的指令都围绕着一个F展开,就像一个爬行中的小龟,我们通过各种指令来控制小龟的爬行路径,最后用路径来描绘我们期望的图形。
转载自:http://ih-dt.org/bbs/viewtopic.php?t=2898
1,最基本的指令,前进的原始动力:F
F即forwords,意思为“向前”,在L-Systems中代表前进一步,步幅默认由默认移动(Default Movement)参数决定
具体格式为:F(长度,比例,细分)
举例:
a,前提(Premise):F
行为结果是沿自身b(z)轴方向前进一步幅,步幅长度等于默认移动(Default Movement)数值。
b,前提(Premise):F(2)
行为结果是沿自身b(z)轴方向前进1步幅,步幅长度等于默认移动(Default Movement)数值乘以2,
c,前提(Premise):FFF
行为结果是沿自身b(z)轴方向前进3步幅,每步幅长度等于默认移动(Default Movement)数值。
d,前提(Premise):FF(0.5)
行为结果是沿自身b(z)轴方向前进2步幅,第1步幅长度等于默认移动(Default Movement)数值,第2步幅长度等于默认移动(Default Movement)数值乘以0.5
注:F大写代表前进一步,f小写代表“空”进一步
H就是half,一半的意思,H大写代表前进半步,h小写代表“空”进半步
M就是moves,P就是place,他们都能精确的控制前进坐标,区别是,M以上一步幅的局部坐标为准,p是以全局坐 标为准,基 本格式是p(x,y,z),例如:FM(10)FP(0,0,0)F 前进一步后向x轴方向移动10单位然后回到坐标原点,当然,想回到起始点有更 简单的方法,R,也就是reset,一个指令直接飞回去.....
2,方向的控制:+ - ^ & / \
“-”代表向左,“+”代表向右。方向基于自身当前b(z)轴,其实也就是基于自身当前的h(y)轴向正或反方向旋转,旋转的角度等于默认角度(Default Angle)参数的数值。
“^”代表向上,“&”代表向下。方向基于自身当前b(z)轴,其实也就是基于自身当前的p(x)轴向正或反方向旋转,旋转的角度等于默认角度(Default Angle)参数的数值。
“/”代表向左自转,“\”代表向右自转。方向基于自身当前b(z)轴,其实也就是基于自身当前的b(z)轴向正或反方向旋转,旋转的角度等于默认角度(Default Angle)参数的数值。
具体格式为:旋转方向(角度)
举例:
a, 前提(Premise):F+F-F
行为结果是前进3步幅,第1步沿当前自身b轴方向前进,第2步向左旋转并前进,第2步以当前b轴为准向右旋转并前进,第2、3步的旋转角度等于默认角度(Default Angle)参数的数值。
b, 前提(Premise):F+(30)F-F
默认角度(Default Angle)参数数值为90
行为结果是前进3步幅,第1步沿当前自身b轴方向前进,第2步向左旋转30度并前进,第2步以当前b轴为准向右旋转90度并前进。
3,分裂:[]
"["分支开始,“]”分支结束。凡是被置于[]内的指令都被视为分支,同一层级可以有多个分支存在。
举例:
a,前提(Premise):F[-F][+F]
默认角度30,前进1步后分别向左向右30度生成两个分支,这是一个字母“Y”的形状。
b,前提(Premise):F[-F][+F]F[-F][+F][-(30)F][+(30)F]
默认角度90,这是一个人民币的符号,请试着自己分析一下。
C, 分支可以进行嵌套,也就是分支再分支,比如
前提(Premise):F[-F[+F]F]
前进1步后向左产生分支,分支前进1步后继续前进的同时向右产生一个分支。
4,繁殖的规则:rules
事实上我们应该把前提(Premise)看作是运算的结果,或者是“主干”,而rules就是运算的规则。因为我们不可能仅仅通过Premise中的简单指令实现复杂的分形,所以需要通过定义规则来实现自重复特性。规则很简单,有点像最基础的代数式,举个最简单的例子:
前提:FAF 规则:A=-F 那么实际生成的就是F-FF
也就是说规则中定义了A=-F,前提的运算中就会把A自动转换成-F进行运算,这个“A”可以是除了turtle语言中固定指令外的任意字母,比如“F”“H”“M”等,剩下的自己可以随便定义。
规则中可以定义多个规则,例如:
前提:FABC
规则:A=-F
B=+F
C=^F
实际就是:F-F+F^F
也可以使用多重规则嵌套,例如:
前提:FAF
规则:A=-FB
B=+F
实际就是:F-F+F
规则的存在使得重复的图形可以只通过一次定义生成,比如:
前提:FAFAFAFAFAFAFA
规则:A=[-F-F][+F+F]
麦穗?鱼刺儿?不管他....
规则最精彩的地方,在于自循环,就是不断的重复复制某个“片段”,举个最简单的循环例子:
前提:FA
规则:A=FA
这是一个和容易让人迷糊的公式,因为A=FA,所以FA=FFA,FFA=FFFA,FFFA=FFFFA........所以,A=FA其实是一个F的“自循环”,也就是一直永远的FFFFFFFFFFF.....下去,小龟会一直向前爬到世界末日。那么谁能阻止小龟的前进步伐呢?猜对了,就是生长(Growth)参数的数值,这个参数定义了循环的次数上限,假设这个数值为2的话,FA就等于FF,生长为5的话,FA=FFFFF,换句话说,自循环会不断的重复生成自身,就像一个繁殖的过程,生长值定义了“繁殖”的次数。
再来个稍微复杂一些的自重复:
前提:FA
规则:A=F[-FA][+FA]A
默认角度30
生长值推荐先开到5,太高了会很恐怖。
我们来分析一下这个公式,F[-F][+F]这是个熟悉的图形,就是前面说的“Y”,如果A=F[-F][+F]A,这个也好理解,就是不断的重复F[-F][+F],也就是前面的鱼刺儿无限繁殖版,现在是A=F[-FA][+FA]A,也就是说,除了F[-F][+F]在循环以外,[-F][+F]这两个分支也在进行同样的重复繁殖,这很像树木的生长方式,主干上长出分支,分支上再分支,分支再分支.....我们原本的那个“Y”成了一个基因,不断的复制生长....
5,其他的控制指令
a,“基因”的“衰退”
通过前面的实验,我们一定发现了,繁殖的过程非常的完美,每一次复制都同“父级”完全相同,随机这个参数可以让繁殖的过程产生“变异”,但在自然中分形繁殖的过程是有“衰退”现象的,子级一般会比父级在长度,比例,旋转角度上发生“缩水”现象,这些特性我们无论如何也不会愿意通过手工来实现,所以我们有请 " ; 和 !
" 控制长度衰退
; 控制角度衰退
!控制比例衰退
使用格式是加在任意位置,对,任意位置,这几个指令只会对他们之后的指令产生影响,其中比较特殊的是!比例,这个指令只在将样条进行扫描放样的时候有效,龟样条在放样的时候如果用一个圆作为扫描截面,你会发现圆的直径变化不会影响扫描的结果,龟样条扫描的结果只受到自身的“默认缩放”参数影响,还有就是各指令的括号参数指定比例,最后就是会受到!指令影响产生比例衰退,比如:
前提:FA
规则:A=!";F[-FA][+FA]A
b,关于细分
刚开始我们就提到过F使用规则是F(长度,比例,细分),长度比例容易理解,那么细分是干嘛用的呢?细分其实就是给每步幅的样条增加节点数量,假如我们需要做一棵树或一段树枝,最终会将“龟样条”进行放样和平滑细分处理,这时候,原本的每步幅只有开始和结束两个节点的样条会在细分后将“拐弯”的地方变得非常“圆滑”,有建模经验的一定知道,增加每步幅的节点数量是最好的解决方案。举例, F(1,1,3) 长度比例保持不变,样条细分为3。
c,关于I J K L
在规则定义中,IJKL这四个字母和FMH等一样不要用,因为他们有特殊的含义,他们代表特定的“组”。
我们可以把“龟”样条作为克隆的参考对象,将一些几何体克隆到样条上,比如树枝上长满树叶或枝头结满果子。但树叶和果子都要长,我们该怎样分别控制他们的位置呢,我们有多个克隆对象该怎么区分呢?这里时候这四个字母就有用了。克隆对象的参数中有一个“分布”选项,除了“数量”“平均”“步幅”这些我们熟悉的选项,还有四个组,这四个组就分别对应IJKL。
举个例子,我们有一个“龟样条”:FF[-F][+F]FF,恩,一个带两个分支的树杈。我们建立两组克隆,一组克隆树叶,一组克隆花朵,并且两组克隆的克隆对象都指定为龟样条,然后将树叶的分布设为“组1”,也就是I,花的分组设为“组4”,也就是K。最后,我们修改前提:FF[-FI][+FI]FFK,现在,分支上长出了树叶,钉梢上开出了花朵......
d,建立poly
如果你愿意,可以让龟样条建立多边形,规则是{.F.F.F}
{}中的指令将生成poly
.代表生成一个poly的顶点
举例:默认角度90 {.F.+F.+F.+F} 这是一个正方形
默认角度30 {.+F.++++F+(120)F} 这是一个等边三角形,注意一些指令是可以累积的,+是右转30度,++++就是右转120度,当然你也可以用+(120)来直接定义角度数值。
e,向性(Tropism)
向性的指令是T,默认情况下向性是向下的,你可以将其视为“重力”,这个指令会将其后的所有指令往下“压”,压力随着步幅的层级越来越强,压得力度由“趋向性”参数指定。例如我们前面提到的例子:
前提:FA
规则:A=TF[-FA][+FA]A
有趣的是,增加向性指令后,样条就会收到粒子力学系统的的影响,比如风力,反弹和湍流引力等,这是模拟真实植物力学现象的强力指令,超赞!
f,用户数据
龟语言同c4d完美结合的体现之处,除了上面提到的“向性力学”外,就是这个用户数据参数了。没错,龟语言支持通过用户数据指定参数,方便参数的调整。使用方法很简单,只要用相同的参数名就可以了,比如在用户数据中建立一个参数名为“LBS”,然后写入前提公式:F+(LBS)F ,这样,+的角度参数就被用户数据中的LBS控制了,不过可惜的是不支持中文数据名。注意,给用户数据命名时尽量不要使用语言中有相关指令的字母以免发生错误运算。
后记:Turtle语言其实并不难学,规则简单,特定指令不多,而且很有趣。难的是应用,用Xfrog插件做个花花草草的比较容易,但初学者用L_Systems做出一株漂亮的植物就难多了,因为要完全改变常规的制作方式和思维模式,但只要愿意下功夫,稍作了解就能快速入门,多思考多实践,就一定能渐入佳境,领略到L_Systems的强大之处,因为最近手头工作比较忙,没时间写更详细的教程和制作一些具体的实例教学,只能在工作累了的时候写些简单的文字说明,断断续续的写了两三天,其中难免可能有写错的地方,或者是漏掉的地方,大家请谅解,希望大家能多多交流Turtle语言,分享自己的心得,最后,祝大家龟游快乐!
1,最基本的指令,前进的原始动力:F
F即forwords,意思为“向前”,在L-Systems中代表前进一步,步幅默认由默认移动(Default Movement)参数决定
具体格式为:F(长度,比例,细分)
举例:
a,前提(Premise):F
行为结果是沿自身b(z)轴方向前进一步幅,步幅长度等于默认移动(Default Movement)数值。
b,前提(Premise):F(2)
行为结果是沿自身b(z)轴方向前进1步幅,步幅长度等于默认移动(Default Movement)数值乘以2,
c,前提(Premise):FFF
行为结果是沿自身b(z)轴方向前进3步幅,每步幅长度等于默认移动(Default Movement)数值。
d,前提(Premise):FF(0.5)
行为结果是沿自身b(z)轴方向前进2步幅,第1步幅长度等于默认移动(Default Movement)数值,第2步幅长度等于默认移动(Default Movement)数值乘以0.5
注:F大写代表前进一步,f小写代表“空”进一步
H就是half,一半的意思,H大写代表前进半步,h小写代表“空”进半步
M就是moves,P就是place,他们都能精确的控制前进坐标,区别是,M以上一步幅的局部坐标为准,p是以全局坐 标为准,基 本格式是p(x,y,z),例如:FM(10)FP(0,0,0)F 前进一步后向x轴方向移动10单位然后回到坐标原点,当然,想回到起始点有更 简单的方法,R,也就是reset,一个指令直接飞回去.....
2,方向的控制:+ - ^ & / \
“-”代表向左,“+”代表向右。方向基于自身当前b(z)轴,其实也就是基于自身当前的h(y)轴向正或反方向旋转,旋转的角度等于默认角度(Default Angle)参数的数值。
“^”代表向上,“&”代表向下。方向基于自身当前b(z)轴,其实也就是基于自身当前的p(x)轴向正或反方向旋转,旋转的角度等于默认角度(Default Angle)参数的数值。
“/”代表向左自转,“\”代表向右自转。方向基于自身当前b(z)轴,其实也就是基于自身当前的b(z)轴向正或反方向旋转,旋转的角度等于默认角度(Default Angle)参数的数值。
具体格式为:旋转方向(角度)
举例:
a, 前提(Premise):F+F-F
行为结果是前进3步幅,第1步沿当前自身b轴方向前进,第2步向左旋转并前进,第2步以当前b轴为准向右旋转并前进,第2、3步的旋转角度等于默认角度(Default Angle)参数的数值。
b, 前提(Premise):F+(30)F-F
默认角度(Default Angle)参数数值为90
行为结果是前进3步幅,第1步沿当前自身b轴方向前进,第2步向左旋转30度并前进,第2步以当前b轴为准向右旋转90度并前进。
3,分裂:[]
"["分支开始,“]”分支结束。凡是被置于[]内的指令都被视为分支,同一层级可以有多个分支存在。
举例:
a,前提(Premise):F[-F][+F]
默认角度30,前进1步后分别向左向右30度生成两个分支,这是一个字母“Y”的形状。
b,前提(Premise):F[-F][+F]F[-F][+F][-(30)F][+(30)F]
默认角度90,这是一个人民币的符号,请试着自己分析一下。
C, 分支可以进行嵌套,也就是分支再分支,比如
前提(Premise):F[-F[+F]F]
前进1步后向左产生分支,分支前进1步后继续前进的同时向右产生一个分支。
4,繁殖的规则:rules
事实上我们应该把前提(Premise)看作是运算的结果,或者是“主干”,而rules就是运算的规则。因为我们不可能仅仅通过Premise中的简单指令实现复杂的分形,所以需要通过定义规则来实现自重复特性。规则很简单,有点像最基础的代数式,举个最简单的例子:
前提:FAF 规则:A=-F 那么实际生成的就是F-FF
也就是说规则中定义了A=-F,前提的运算中就会把A自动转换成-F进行运算,这个“A”可以是除了turtle语言中固定指令外的任意字母,比如“F”“H”“M”等,剩下的自己可以随便定义。
规则中可以定义多个规则,例如:
前提:FABC
规则:A=-F
B=+F
C=^F
实际就是:F-F+F^F
也可以使用多重规则嵌套,例如:
前提:FAF
规则:A=-FB
B=+F
实际就是:F-F+F
规则的存在使得重复的图形可以只通过一次定义生成,比如:
前提:FAFAFAFAFAFAFA
规则:A=[-F-F][+F+F]
麦穗?鱼刺儿?不管他....
规则最精彩的地方,在于自循环,就是不断的重复复制某个“片段”,举个最简单的循环例子:
前提:FA
规则:A=FA
这是一个和容易让人迷糊的公式,因为A=FA,所以FA=FFA,FFA=FFFA,FFFA=FFFFA........所以,A=FA其实是一个F的“自循环”,也就是一直永远的FFFFFFFFFFF.....下去,小龟会一直向前爬到世界末日。那么谁能阻止小龟的前进步伐呢?猜对了,就是生长(Growth)参数的数值,这个参数定义了循环的次数上限,假设这个数值为2的话,FA就等于FF,生长为5的话,FA=FFFFF,换句话说,自循环会不断的重复生成自身,就像一个繁殖的过程,生长值定义了“繁殖”的次数。
再来个稍微复杂一些的自重复:
前提:FA
规则:A=F[-FA][+FA]A
默认角度30
生长值推荐先开到5,太高了会很恐怖。
我们来分析一下这个公式,F[-F][+F]这是个熟悉的图形,就是前面说的“Y”,如果A=F[-F][+F]A,这个也好理解,就是不断的重复F[-F][+F],也就是前面的鱼刺儿无限繁殖版,现在是A=F[-FA][+FA]A,也就是说,除了F[-F][+F]在循环以外,[-F][+F]这两个分支也在进行同样的重复繁殖,这很像树木的生长方式,主干上长出分支,分支上再分支,分支再分支.....我们原本的那个“Y”成了一个基因,不断的复制生长....
5,其他的控制指令
a,“基因”的“衰退”
通过前面的实验,我们一定发现了,繁殖的过程非常的完美,每一次复制都同“父级”完全相同,随机这个参数可以让繁殖的过程产生“变异”,但在自然中分形繁殖的过程是有“衰退”现象的,子级一般会比父级在长度,比例,旋转角度上发生“缩水”现象,这些特性我们无论如何也不会愿意通过手工来实现,所以我们有请 " ; 和 !
" 控制长度衰退
; 控制角度衰退
!控制比例衰退
使用格式是加在任意位置,对,任意位置,这几个指令只会对他们之后的指令产生影响,其中比较特殊的是!比例,这个指令只在将样条进行扫描放样的时候有效,龟样条在放样的时候如果用一个圆作为扫描截面,你会发现圆的直径变化不会影响扫描的结果,龟样条扫描的结果只受到自身的“默认缩放”参数影响,还有就是各指令的括号参数指定比例,最后就是会受到!指令影响产生比例衰退,比如:
前提:FA
规则:A=!";F[-FA][+FA]A
b,关于细分
刚开始我们就提到过F使用规则是F(长度,比例,细分),长度比例容易理解,那么细分是干嘛用的呢?细分其实就是给每步幅的样条增加节点数量,假如我们需要做一棵树或一段树枝,最终会将“龟样条”进行放样和平滑细分处理,这时候,原本的每步幅只有开始和结束两个节点的样条会在细分后将“拐弯”的地方变得非常“圆滑”,有建模经验的一定知道,增加每步幅的节点数量是最好的解决方案。举例, F(1,1,3) 长度比例保持不变,样条细分为3。
c,关于I J K L
在规则定义中,IJKL这四个字母和FMH等一样不要用,因为他们有特殊的含义,他们代表特定的“组”。
我们可以把“龟”样条作为克隆的参考对象,将一些几何体克隆到样条上,比如树枝上长满树叶或枝头结满果子。但树叶和果子都要长,我们该怎样分别控制他们的位置呢,我们有多个克隆对象该怎么区分呢?这里时候这四个字母就有用了。克隆对象的参数中有一个“分布”选项,除了“数量”“平均”“步幅”这些我们熟悉的选项,还有四个组,这四个组就分别对应IJKL。
举个例子,我们有一个“龟样条”:FF[-F][+F]FF,恩,一个带两个分支的树杈。我们建立两组克隆,一组克隆树叶,一组克隆花朵,并且两组克隆的克隆对象都指定为龟样条,然后将树叶的分布设为“组1”,也就是I,花的分组设为“组4”,也就是K。最后,我们修改前提:FF[-FI][+FI]FFK,现在,分支上长出了树叶,钉梢上开出了花朵......
d,建立poly
如果你愿意,可以让龟样条建立多边形,规则是{.F.F.F}
{}中的指令将生成poly
.代表生成一个poly的顶点
举例:默认角度90 {.F.+F.+F.+F} 这是一个正方形
默认角度30 {.+F.++++F+(120)F} 这是一个等边三角形,注意一些指令是可以累积的,+是右转30度,++++就是右转120度,当然你也可以用+(120)来直接定义角度数值。
e,向性(Tropism)
向性的指令是T,默认情况下向性是向下的,你可以将其视为“重力”,这个指令会将其后的所有指令往下“压”,压力随着步幅的层级越来越强,压得力度由“趋向性”参数指定。例如我们前面提到的例子:
前提:FA
规则:A=TF[-FA][+FA]A
有趣的是,增加向性指令后,样条就会收到粒子力学系统的的影响,比如风力,反弹和湍流引力等,这是模拟真实植物力学现象的强力指令,超赞!
f,用户数据
龟语言同c4d完美结合的体现之处,除了上面提到的“向性力学”外,就是这个用户数据参数了。没错,龟语言支持通过用户数据指定参数,方便参数的调整。使用方法很简单,只要用相同的参数名就可以了,比如在用户数据中建立一个参数名为“LBS”,然后写入前提公式:F+(LBS)F ,这样,+的角度参数就被用户数据中的LBS控制了,不过可惜的是不支持中文数据名。注意,给用户数据命名时尽量不要使用语言中有相关指令的字母以免发生错误运算。
后记:Turtle语言其实并不难学,规则简单,特定指令不多,而且很有趣。难的是应用,用Xfrog插件做个花花草草的比较容易,但初学者用L_Systems做出一株漂亮的植物就难多了,因为要完全改变常规的制作方式和思维模式,但只要愿意下功夫,稍作了解就能快速入门,多思考多实践,就一定能渐入佳境,领略到L_Systems的强大之处,因为最近手头工作比较忙,没时间写更详细的教程和制作一些具体的实例教学,只能在工作累了的时候写些简单的文字说明,断断续续的写了两三天,其中难免可能有写错的地方,或者是漏掉的地方,大家请谅解,希望大家能多多交流Turtle语言,分享自己的心得,最后,祝大家龟游快乐!