RhinoScript入门.docx
《RhinoScript入门.docx》由会员分享,可在线阅读,更多相关《RhinoScript入门.docx(17页珍藏版)》请在冰豆网上搜索。
RhinoScript入门
RhinoScript可以翻译为“犀牛脚本”。
RhinoScript是架构在VisualBasic语言之上的Rhino专属程序语言,大致上又可分做Marco与Script两大部分。
以下简单地说明Marco与Script两者之间的差别。
Marcos(可以称做宏)就像是一个口令一个动作的叫Rhino帮我们执行「动作」(actions)。
Marco的命令行是线性、静态的,意思就是说,如果我们下了一百条指令,Rhino就会从第一条、第二条、第三条、、、这样一路执行到第一百条命令,无法跳跃也无法重复执行某个命令。
Scripts则是动态且非线性的。
首先,透过Flow Control我们可以跳过或者重复某些命令行,而VariableControl则可以让我们创造出逻辑与数学的运算,InputandOutput(I/O)则是使用者与Rhino之间的互动,使用者可以送进许多种类型的资料(data),再经过运算之后以许多种数据形态输出。
在了解Marcos与Scripts之间的差别之后,我们首先开始来介绍一点简单的「语法」(syntax)。
在计算机程序语言中的语法,其实就跟我们学英文或其他外国语言一般,我们需要背单词也需要学文法,而在此的语法就有点像是文法。
因此,语法就是一种「成套」(aset)的规则组合。
于是乎,当然也就会有所谓合法与不合法的语法,只不过,一般日常生活中,如果我们说出不合文法的语句,人基本上还可以透过上下文来猜懂。
但是,计算机就没这么聪明了,如果我们写出不合语法的命令行,计算机不但不会去猜,根本就不理会,只会告诉我们:
「描述方式有误」、「语法不合规定」等警告句,告诉我们必须回头去检查到底是哪句命令行说错了。
RhinoScript所使用的VB语言的语法基本上算是简单的,已经非常接近日常的口语,这算是非信息背景用户的一大福音(版主也是这两个月才真的开始学程序)。
所以,以下我们就来简单说明一下在Rhino中会用到的几种基本语法。
如果我们要画一条线,我们大概会这么说:
「画一条线,起点在坐标(0,0,0)的位置,端点在(10,0,0)的位置。
」同样地,在Rhino的Marco命令行我们可以这么下指令(请开启Tools\Commands\MarcoEditor):
_Line0,0,010,0,0
然而,如果我们不是在Marco中,而是在Script的环境下(请开启Tools\RhinoScript\Edit),会有两种说法。
一种就像是直接在Rhino工作接口中的Command列下指令一般,可以这样讲:
Rhino.Command"_Line0,0,010,0,0"
另一种讲法,则是呼叫RhinoScript中内部建构的许多Methods(超过200种),所以我们应该写成:
CallRhino.AddLine(Array(0,0,0),Array(10,0,0))
基本上,本文的目的不在于将所有指令或者Rhino内建的Methods解说完毕,用意只在于很简单地说明在计算机语言中的语法与日常用语中文法的关系。
差别只在于,「计算机还挺很忠心的,我们叫他做啥,他就会做啥」(这是陈教授的名言之一)。
所以,如果指令下了,Rhino却没反应,决不是Rhino有错,赶紧回头检查自己的命令行是否下错了。
此外,如果要详细了解VB的语法可以参考网络上的Microsoft教学手册,可以免费下载并且有中文版。
如果想详细了解RhinoScript中所有Methods的语法,请开启Help\Plug-ins\RhinoScript,这里头详细记载了每个Mehods的用途、语法以及回传(return)值等说明,当然,如果各位不心急的话,之后我们也会一一提到。
在了解RhinoScript的基本语法之后,我们这次要说明的是VB中的「循环」(Loops)种类与概念。
VB的循环基本上可以分为三种:
(1)For...Next(计数循环)、
(2)Do...Loop(条件式循环)、(3)ForEach...In...Next(数组循环)。
三种循环的特色与用法各有不同,端看在何种需要来选择。
举例来说,计数循环顾名思义就是指当我们已经知道某一个数量时所使用;而条件式循环则是循环本身具有条件的设定功能,透过条件的符合与不符合判断可以决定进入循环或者离开循环;数组循环则是将在一个「数组」(array)中的对象一一取出来执行某些命令动作。
将上述的循环种类与表达方式整理如下:
(1)计数循环
For...Next
(2)条件式循环
DoWhile...Loop(前侧式)
DoUntil...Loop(前侧式)
Do...LoopWhile(后测式)
Do...LoopUntil(后测式)
Do...Loop(无穷)
While...Wend(如果为真)
(3)数组循环
ForEach...In...Next
接下来,我们就一一说明上述的循环运用方式以及提供简易的范例。
先从计数循环说起,如果我们执行下列程序,我们可以在Rhino工作接口的Command列看到Rhino当我们印出"1"。
DimA:
A=1
CallRhino.Print(A)
以此类堆,如果我们要依序印出"12345678",当然可以很辛苦地这么写:
DimA:
A=1
DimB:
B=2
DimC:
C=3
DimD:
D=4
DimE:
E=5
DimF:
F=6
DimG:
G=7
DimH:
H=8
CallRhino.Print(A)
CallRhino.Print(B)
CallRhino.Print(C)
CallRhino.Print(D)
CallRhino.Print(E)
CallRhino.Print(F)
CallRhino.Print(G)
CallRhino.Print(H)
但是计算机如果真的只能这么笨地一个口令一个动作,那我会请各位现在就放弃吧!
这时候如果我们运用计数循环,为得到同样的结果,可以改成这么写:
Dimi
Fori= 1To8
CallRhino.Print(i)
Next
这就是所谓的计数循环,当我们已知某个数量(从1到8),就可以利用计数循环重复执行某个动作,而在此所定义的"i"是个变量,每次重新进入循环时,"i"值会被替换为下一个数字。
因此,如果我们很快地将计数循环结合RhinoScriptMethods,试着执行下列的指令看看:
DimStratPoint,EndPoint
Dimi
Fori=0To10
StartPoint=Array(i*10,0,0)
EndPoint=Array(i*10,10,0)
CallRhino.AddLine(StartPoint,EndPoint)
Next
我们可以很快地得到11条线,每条线的长度都是10,间距也都是10,第一条线的起点为(0,0,0)终点为(0,10,0),每个下一条线则是间距上一条线10的单位的并行线。
如果善加利用计数循环与函数规则,就可以做出许多复杂的形体,不仅可省下许多力气,也可能会产生出一些出乎意料的形体。
这次只是简单地介绍了计数循环的最基本用法,之后我们分别会再说明其他种类循环的基本用法,并且提供一些比较复杂的循环组合运用方式。
04=IntorductiontoRhinoScript(Loops-2&Comparisons)
AnShortIntroductiontoRhinoscript
本文接着要说明上文所提到的条件式循环,但因为这会运用到VB语言中的「比较」(comparisons)功能,因此,一开始我们将先就此部分做说明。
在VB中的比较式其实已经非常接近一般的数学式,详细如下:
A = B AandBareequal
A<>B AandBarenotequal
A>B AisgreaterthenB
A>=B AisgreaterthenorequaltoB
A
A<=B AislessthenorequaltoB
有了上述比较式的概念,我们就可以开始说明条件式循环了。
首先,我们说明两个前侧式循环:
DoWhile...Loop以及DoUntil...Loop。
如果我们用口语的方式来翻译,会像是下面的说法:
DoWhile...Loop 当符合***,就一直做
DoUntil...Loop 一直做,直到符合***为止
上述口语翻译中的***其实就是一个条件式,因此,DoWhile...Loop的意思就是,当条件式成立时就进入循环,直到条件式式不成立才离开循环接着下一个命令行执行下去。
而DoUntil...Loop则是如果一开始条件式不成立就进入循环,不断重复到条件式成立才离开循环接着下一个命令行执行下去。
这两个循环的正式语法如下:
DoWhile
Statement(s)
Loop
------------------------------------
DoUntil
Statement(s)
Loop
而另外两个后测式循环的语法基本上与前测式循环类似,唯一的差别只在于进入循环的先后顺序,在一般状态下前测式与后测式循环是不具差别的,但若要细微地控制进入循环的时间点就必须要特别留意了。
举例来说,DoWhile...Loop是先判断条件式是否成立,若成立才进入循环的「叙述区块」(statements),而Do...LoopWhile则是先进入循环中的叙述区块,再判断条件式是否成立,若成立则重复进入循环,若不成立则离开循环。
两个后测式循环的语法如下:
Do
Statement(s)
LoopWhile
-------------------------------------
Do
Statement(s)
LoopUntil
还有两个循环我们还没介绍,由于Do...Loop这个无限循环一般来说在RhinoScript很少使用,另一方面也经常会造成问题与困扰,所在此将不做说明。
但是,另一个While...Wend则经常使用,甚至应该说很好用,所以大家可以特别注意一下,其口语翻译如下:
Whlie...Wend 当***为真就做,一直到***为假
在此的***依旧是个条件式,整个循环的运作过程就是当条件式为「真」(True),则进入循环中的叙述区块,接着当进行到Wend的语句时,再回去检查一开始的条件式是否依旧为真,若为真就一直重复这些动作,直到当条件式为「假」(False)则离开循环接着下一个命令行执行下去。
其正式语法如下:
Whlie
Statement(s)
Wend
接下来,我们要对计数循环与条件式循环做个简单的比较来说明两者的适用时机。
请比较下列两个循环:
Dimi
Fori=0To10
CallRhino.Print(i)
Next
-------------------------------------------
Dim n:
n=1
DoWhilen<=10
CallRhino.Print(n)
n=n+1
Loop
若各位有实际测试,应该会发现到得到的结果是相同的。
那么,For...Next循环与Do...Loop循环的差别究竟在哪里?
我们可以发现,For...Next循环一开始就必须知道循环的执行次数,而Do...Loop循环则不用知道循环的执行次数。
也就是说,当我们可以确认循环的执行次数时,将建议使用计数循环。
但是,有些时候我们无法得知循环的执行次数,这时候就应该用条件式循环。
此外,循环彼此还可以互相搭配,产生循环内还有循环,也就是所谓的「巢状循环」(NestedLoop),这类相对目前来说比较复杂的运用之后我们会在实际范例中进行说明。
05=IntroductiontoRhinoScript(TextflieLayout)
AnShortIntroductiontoRhinoScript
在进入其他VB语言与RhinoScript的说明之前,先提示一点轻松但是却重要的提醒。
由于其实写程序就跟做设计很类似,设计者如果没有良好的档案管理方法,经常会图纸乱丢又乱塞,等到某天想要用时却找不到,就算找到了也忘记这张图到底是何时完成的,或者忘了最后的版本是谁修正的。
当我们程序越写越多时也会面临到上述的情形,因此,保持良好的工作习惯以及建立正确的档案管理统对日后不仅有莫大的帮助也是不可或缺的必备功课。
另一方面, 一个程序除了要让计算机读得懂之外,常常也要让朋友或者是其他使用者能够阅读,于是乎,有一些共通的标注方式,就变成不同用户要读懂程序的重要媒介。
一般来说,一个较为完整的VBScript会由四个部分所组成:
(1)OptionExplicitarea(语句区块)、
(2)Main subroutine(主要的子程序)、(3)Addtionalsubroutinesandfunctions(附加的子程序与函数式)、(4)Executioncommenting(执行批注),其详细说明如下:
(1) OptionExplicitarea
在VB语言中,当我们在程序的一开始加上了OptionExplicit这个语句,表示我们在模块中的所有变量都必须以Dim,ReDim,Public,Private,Static等语句(这些语句我们之后会另行说明)来加以宣告。
若有出现未宣告的变量,在模块的编译阶段会以错误方式警示告知。
OptionExplicit必须放在所有程序(Subs,Functions)之前,加上它的好处是:
可以帮我们检查是否输入错误的变量名称,或是有某些变量被重复定义。
另外,一般来说,我们会在这个区加上一些「批注列」(commentinglists)来说明作者、建档日期以及参考来源。
在VB语言中,当我们在某段字符串前方加上撇号(apostrophe,即'),VB就会略过这段字符串不读,也就是成为单纯的叙述文字。
OptionExlicit语法范例如下:
OptionExplicit
'Scriptwrittenby
'Scriptcopyrightedby
'Scriptversion
(2)Mainsubroutine
VB语言中的Mainsubroutine由四个部分所组成,语法如下:
SubMain()
EndSub
上面这个范例句是没有其他子程序(Subs)的情况,若有其他的子程序,在SubMain()与EndSub之间则放放进呼叫其他子程序的语句。
(3)Additionalsubroutinesandfunctions
在VB语言中,Subs与Functions 几乎可以做相同的事。
但是,Functions可以有「回传值」(returns)来做运算的动作,而Subs则无法。
因此,通常我们将一些数值的运算交给Functions来做。
另外,在VB中Function可以自己呼叫自己,也就是可以做出「递归」(recursion)运算,而且呼叫Function时可以在其左方直接加上一些函数表达式(像是:
Sqr、Cos或Chr等),使Function就如同是内建函数一般。
比较详细的Function实际使用方式之后会进一步说明,在此仅作初步介绍。
最后,我们经常会在Sub或Function的名称左方看见一对括号,这表示可以送入变量,在VB中,Sub与Function都可以送入变量,而当我们即使不送入变量时,也会以空的括号来表示。
(4)Excutioncommenting
通常我们会在模块中将某些重要的程序做批注,批注的方式请参照本文一开始所提到的commenting。
做批注的好处是提醒自己日后在程序越写越复杂时,方便检查与阅读,另外也提供其他用户了解程序内容的用途。
此外,一个好的程序撰写者经常会在一个复杂程序的最后端加入一系列的步骤分解批注,用以说明整个程序执行过程的每个「步骤」(step)用途。
最后,一个RhinoScript的档案会被存成"*.rvb"的文件格式,在此的"rvb"即是代表"RhinoVisualBasic"。
本文主要是说明RhinoScript档案的格式与良好的完整程序架构,内文中所碰触到的一些新知识若有位详细说明之处,都会在之后陆续提供详细的解说。
06=IntroductiontoRhinoScript(Oprators&Functions)
AnShortIntroductiontoRhinoScript
这次我们要简单介绍几个在VB语言中经常出现的几种不同类型的「码」(code)。
在说明之前,请先看下列例子:
A=10+20
B=10+20*0.5
A=Sin(10+20)+Sqr(0.5)
B=Tan(10+20)/Log(0.5)
在这面的这几个式子中出现了四种类型VB语言码:
(1)Numbers(数值)、
(2)Variables(变数)、(3)Operators(运算符)、(4)Functions(函数)。
(1)Numbers&
(2)Variables
在VB中,数字可以是整数或具有小数点,同时也可是正数或负数。
式子中的 A,B我们称为变量,在VB语言中所有变量都必须被宣告,而宣告的方式有很多种,最常用的宣告语句是Dim,在VB中Dim的意思基本上就像是定义。
当我们在宣告陈述区写下DimA,B,表示计算机会为我们预先留下内存的位置给A,B这两个变量。
有时后我们也会看见有人这样写:
DimAAsString,这样的写法是事先告诉计算机这个变量的数据类型,差别在于因为不同的数据类型计算机为我们预先留下的内存位数(bits)是不同的。
不过,这时候我们还不需要了解的如此深入,只要知道变量的宣告方式即可,其他的知识大略有个概念即可。
另外,上面范例式中的"=",在数学式中是表示「等于」的概念,但是在计算机语言中用「等于」来解释会出现问题。
譬如说,如果我们写下N=N+1的式子,这在数学中是不成立的,因为如果我们将N以1带入,那1=1+1当然就不成立。
因此,在计算机语言中"="的概念是:
将"="右边的答案或结果代入左边的变量。
我们用下面的例子做个简单的练习:
DimA
A=10+20
A=A+1
CallRhino.Print(A)
我们会发现答案是31。
为什么?
因为VB语言的程序代码是由上往下读的,例子中第一行的意思是:
宣告一个A变量;第二行的意思是:
将10+20的结果代入A,所以这时候的A是30;第三行的意思是:
将A加1之后再带入A所以最后A是30+1也就是31。
(3)Operators
再来要说明的就不这么复杂了,在VB语言中的运算符大致可以分为三类:
数学运算符、逻辑运算符、布尔值(boolean values)运算符。
逻辑运算符在先前的文章中已经做过说明本文就不再重复,数学运算符则相当容易理解,基本上数学运算符的功能跟数学上的方法相同只需要了解其在于VB中表达与运用的方式即可。
另外,布尔值运算符在此只做简单的介绍,详细的用法及概念会在之后详细说明。
+ addtwovalues
- substract