- UID
- 415862
- 积分
- 0
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2006-4-4
- 最后登录
- 1970-1-1
|
发表于 2006-4-10 00:56:32
|
显示全部楼层
--------------------------------------------------------------------------------
单元一:AutoLISP主角潇洒登场
一. AutoLISP 是何方神圣?
1. AutoLISP是AutoCAD的最佳拍檔!
2. AutoLISP内含于AutoCAD软件内,不用另外花钱买!
3. AutoLISP是强化AutoCAD最好、最直接的『程序语言』!
4. AutoLISP易学、易用,即使不会程序设计的AutoCAD使用者,都能在最短的时间内,写出令人惊讶、赞叹的功能!
5. 若说AutoLISP的出现,是替 AutoCAD 创造一片天的『最大功臣』,实不为过一点也不夸张!
6. AutoLISP希望您去学习它、改善它、发挥它、享受它.真的!它的威力、魅力无穷!
二. AutoLISP 程序语言的特质分析:
学习AutoLISP是非常容易的,对初学者而言,即使没有学习过任何的程序语言,都能很快的上手,写出精彩漂亮的AutoLISP程序!
语法简单
不用特殊的变量宣告,非常富有弹性,比起其它的程序语言,它的语法可说是非常简单而有其独特的风格!
功能函数强大
除一般性的功能函数外,又拥有为数不少控制配合AutoCAD的特殊函数,再加上AutoLISP可直接呼叫执行所有AutoCAD的指令,以及掌握运用所有的AutoCAD系统变量,功能之强大令人欣喜不已!
撰写的环境不挑剔
只要是一般的文书编辑软件都适用! 如:Windows的记事本、PE2、PE3、DW3、书中仙、汉书、EDIT....等
直译式程序
不用再作编译,『即写即测、即测即用』,马上可以在AutoCAD中响应效果,马上就有成就感!
横跨各作业平台
悠然自得,虽然AutoCAD有DOS、Windows版本之分但是AutoLISP却可在不改写的原貌下,加载与执行!
三.撰写 AutoLISP 的动机?
1. 欲强化 AutoCAD 原有指令时.
2. 欲创造更有用的 AutoCAD 新指令.
3. 欲简化繁琐的环境设定或绘图步骤时.
4. 欲处理参数式绘图时.
5. 欲做图面资料读文件、写文件.
6. 欲做 AutoCAD 演示文稿展示时.
7. 欲达到真正灵活掌控 AutoCAD 时.
8. 欲提升自己跨上 AutoCAD 高手列车时.
四.AutoLISP 的效益评估?
1. 对公司负责人或设计主管而言:
A.
也许某员工或干部花了20个小时撰写一个AutoLISP程序,表面上,这将近三天的时间,他连一张图都没有画,甚至可能偶有发呆、沉思,若此程序一天可以替公司绘图部门节省1小时绘图时间,那算一算,只要20天就抵销开发成本,而20天以后都是赚的,『用的愈久,省的愈多』!
B.
若员工皆有此动力,在不影响正常工作,『鼓励』都来不及,那有『压抑』的道理,甚至还要派遣优秀人员出去受训,学习更好的设计技巧与创意呢?!
C.
千万不要因为您的不懂或压抑,SHOW您的权威与POWER,如此,不但对员工造成打击,甚至您可能成为阻碍了公司计算机化进步的罪魁祸首
D.
当然,若要撰写的程序很多,内部设计人员的程序功力距离太远,达成需求的时间反而变得遥遥无期,那倒不如求助于市面上已有的相关 AutoCAD 支持软件。
2. 对设计人员而言:
A.
得到一笔提升绩效奖金呢? 当然,无形中,『AutoCAD 高手的封号』也将黄功力又往前迈出了一大步,对个人的成长帮助匪浅,幸运的话,搞不好还可以袍加身,不亦乐乎!!!
B.
『半桶水、响叮当』,千万不要因为会写 AutoLISP 程序而自傲、孤僻、嚣张起来,功力的增长,只是让您有更多『服务他人、服务公司』的机会,若自恃过重,宁可不要!
C.
AutoLISP 程序功力的累进,是无远弗届的,千万不要『孤芳自赏』,『人外有人,天外有天』,也许您觉得是『宝贝加三级』的程序,只是其它设计师基本程序中的一部份罢了!
D.
既然 AutoLISP 是 AutoCAD 的『最大功臣』,当然不会轻易被舍弃,如此,您的学习,保证不会白费!
E.
『精益求精』、『虚心求教』、『用心学习、观摩』、『决心成为高手』
3.对程序本身而言:
A.
少少的几行,却可能有『大大满意』的时候!!!
B.
充份掌握了控制、创造 AutoCAD 的『尚方宝剑』,让您在 AutoCAD 的设计运作中『得心应手』,享受无比的快乐与成就感!!!
五.如何有效的学习 AutoLISP ?
1. 先由小程序着手,认识AutoLISP语法规定!
2. 浏览所有的AutoLISP功能函数,重要的功能函数要熟记脑海,俗语说的好『一回生,二回熟』,除非您不用心,否则没有学不好的道理!!!
3. 要懂得偷懒:不要认为在绘图的过程中,繁琐的步骤是合理的,困难的绘图过程是必须忍耐的,试着用AutoLISP解决看看!
4. 多观摩别人的程序设计,吸取精华,像海棉一样=>『吸』、『吸』、『吸』!!!
5. 动手『写』程序比用眼睛看程序,更能够领略深记脑海!
6. 随时随地整理您的程序,并加以批注,以免因时间的飞逝,当时用心的成果也烟消云散,忘的一乾二净!!!
7. 『决心』是学好 AutoLISP 最重要的关键!
8. 期许自己,要由操作者变成创造者!!!
--------------------------------------------------------------------------------
单元二:AutoLISP的关键、基本结构及语法
一、学好 AutoLISP 的关键、 基本结构与语法:
1. AutoLISP 程序语言的特质
A.语法简单
B.功能函数强大
C.撰写的环境不挑剃
D.直译式程序,『即写即测、即测即用』
E.横跨 AutoCAD 各作业平台,悠然自得 (注:以上五点,读者可以参考上一章的剖析!!!)
2.学好 AutoLISP 的关键:充份掌握『语法结构』&『功能函数』的搭配!!!
3.重要的 AutoLISP 的基本语法结构
规则1: 以括号组成表达式,、相对称左右括号数一定要成双成对
规则2: 表达式型态:( 操作数运算子运算子 运算子)
1.1 操作数包括『功能函数』&『自定函式』
1.2 运算子(自变量)包括:
A.整数(Integer) 如 8,-17,500,9999 .....
B.实数(Real) 如 8.5,-17.456 .....
C.字符串(String) 如 "AutoCAD","123"
D.串行(List) 如 ("a" "b" "c"),(x y)
E.像素名称代码 如 <entity name: 6000f262>
F.档案代码 如 <file:#12438>.....
G.选择群集代码 如 <Selection set:1>
规则3:表达式中的『运算子』,可以是另一『表达式』或『子程序』
规则4: 多重的括号表达式,运算的先后顺序是『由内而外、由左而右』
规则5: 以档案型态存在的 AutoLISP 程序(ASCII 档案),其扩展名必须是.lsp
规则6: 撰写的环境,只要是一般的文书编辑软件、记事本,可编辑 ASCII 档案者都适用
规则7: 以 defun 功能函数定义新的指令或新的功能函式
规则8: 新定义的功能函式名称,若为『C:函式名』,则此函式可为 AutoCAD新指令
规则9: 加载 AutoLISP 程序的作法:=> 指令:后直接键入 (load "LISP主檔名")
规则10: AutoLISP 程序中,在『分号 ;』后的内容均为批注,程序不处理,适时的增加批注,将使程序更具可看性、学习性及完整性
规则11: AutoLISP 最常用的变量型态是『整数』、『实数』、『字符串』、『点串行』四种,变量的型态依据设定值而自动定义,变量会一直储存该值,直到被重新设定值或绘图结束自动消失
规则12:以 setq 功能函数设定变量值 (setq 变量名称 设定值)
规则13:欲在 AutoCAD 的环境中,查看一变量值,指令:下键入『!变量名』即可
规则14:以(defun C:函式名(自变量 / 变量) ........)程序中,程序中的变量若在『/』右边变量内,则称为『区域变量』,否则为『整体变量』
--------------------------------------------------------------------------------
二、学好 AutoLISP 的关键:
充份掌握『语法结构』&『功能函数』的搭配!!! 其时这个关键亦是学习其它程序语言的关键.
· 『语法结构』AutoLISP 的语法结构规定的并不多,变量不用事先定义及宣告,读者可熟记下一单元有关重要的 AutoLISP基本语法结构,十四条设计上要求的『规则』
· 『功能函数』AutoLISP 之所以能功能如此强大,都有赖功能函数,其成员共约200个:
1. 一般性函数170个
2. ADS 定义特殊函数9个
3. 配合 DCL 交谈框设计函数 22个
各功能函数在使用上要求配合的运算子(自变量)型态,均有其规定,当然,您可不能乱给!
例如:
指令:(+ 1 2 3 "ABC")
传回:error : bad argument type (自变量型态错误)
因为『+』函数不接受字符串,而 "abc" 正是字符串
指令:(rtos "abc")
传回:error : bad argument type (自变量型态错误)
因为『rtos』函数只接受实数转字符串
详细内容可参考下一章『快速浏览 AutoLISP 功能函数』至于各功能函数详细的语法与实例应用,读者请参阅本书『第三篇AutoLISP功能函数详解』
--------------------------------------------------------------------------------
三、重要的 AutoLISP 的基本语法结构:
规则1:以括号组成表达式,左右括号数一定要成双成对、相对称
请依序在『指令:』列 (或指令:) 后面直接键入以下表达式
指令:(+ 1 2 3 4 5) 传回加总和15
指令:(max 14.5 8.9 35) 传回最大值35
指令:(menucmd "p1=*") 显示拉下POP1
指令:(getint "Enter Real:") 传回Enter Real:要求输入一个实数
指令:(setq a (* 12.5 4)) 传回相乘值 50,同时设定给『变量 a』
指令:!a 响应50 (注:! 号可用来查询变量值)
指令:(min 75 a 63) 响应最小值50 (因为变量值a代表50)
错误的范例:
指令:(setq a (* 12.5 4)
1> 传回1>表示少了一个括号
1> ) 此时,只要再补上一个 ) 即可
指令:(setq a (* 12.5 4
2> 传回2>表示少了二个括号
2> )) 此时,只要再补上二个 ) 即可
规则2:表达式型态 (操作数 运算子 运算子 运算子 ...)或 (函数(式) 自变量 自变量 自变量 ...)
或 (函数(式) 元素 元素 元素 ...)
1.1 操作数包括『功能函数』&『自定函式』
功能函数: 如上练习中的 +、max、menucmd、getint、 setq、*、min,详细内容可参考下一章『快速浏览 AutoLISP 功能函数』&『第三篇 AutoLISP功能函数详解』
自定函式: 由设计者自行定义的新函式或子程序
1.2 运算子(又称自变量或元素)包括:
A.整数(Integer): 如8,-17,500,9999…
正常范围: 2的16次方,介于-32768与+32767之间
特殊范围: 若以 float 函数将其转为实数,则范围2的32次方, 介于-2147483648与+2147483647之间
B.实数(Real): 如8.5,-17.456…
正常范围: 带有小数点的数,精度可达 14 位有效数字
C.字符串(String): 如 "AutoCAD","123","Enter Real:","7.5",…
正常范围: 以双引号内夹『字符』为认定,字符数不受限制
D.串行(List): 如 ("a" "b" "c"),(x y),(x y z),("a" 8 3.5),....
正常范围: 以左右括号内夹『元素』为认定,元素型态非常弹性
使用频率: 在 AutoLISP 程序设计中应用非常高
范例说明 : ("a" 8 3.5 kk (1 2))
表示此串行内有五个元素 "a"表示字符串a、8表示整数8、3.5表示实数3.5、kk表示变量kk、(1 2)表示串行(1 2)
2D 点坐标(x y) 表示法 => 以二实数形成串行
3D 点坐标(x y z) 表示法 => 以三实数形成串行
E.像素名称代码:如 <entity name: 6000f262> ...
使用范围: AutoCAD 会自动赋予像素指向代码,透过此代码可找到像素的数据库记录
范例说明: (setq en (entlast))
传回 <entity name: 60000062>
(entget en) 可找到像素的数据库串行
F.档案代码: 如<file:#12438>…
使用范围: 开启(open)档案作读档(r)、写档(w)使用时,所产生的代码,如下:
范例说明:
(setq ffr (open "test.txt" "r")) 响应 <file:#24138>
(setq ffw (open "abc.txt" "w")) 响应 <file:#34812>
G.选择群集代码: 如<Selection set:1>、<Selection set:1>…
使用范围: 一个或数个像素所形成的选择集
范例说明:
(setq ss (ssget))
选取对象: (可选择物体)
选取对象: (可选择物体)
选取对象: (按 [ENTER] 键)
响应 <Selection set:1>
规则3 :表达式中的『运算子』,可以是另一『表达式』或『子程序』功能函数使用语法:
(strcat 字符串1 字符串2 字符串3 ....) 字符串结合功能函数
(getstring 提示) 要求键入一个字符串
(rtos 实数) 将实数转换成字符串
范例说明1: (strcat "abc" "123" "LISP") 传回:"abc123LISP"
范例说明2: (strcat "abc" (getstring "Enter String:" ) (rtos 123.45))
执行结果: Enter String: 键入任一字符串,假设是键入 *HELLO*
响应 "abc*HELLO*123.45"
本例中的strcat函数在语法中要求的『运算子』必须是『字符串』型态
『运算子1』= "abc" 是正常的字符串运算子
『运算子2』= 表达式 (getstring "Enter String:") 传回结果是一字符串 "*HELLO*"
『运算子3』= 表达式 (rtos 123.45) 传回结果是一字符串 "123.45"
规则4:多重的括号表达式,运算的先后顺序是『由内而外、由左而右』
范例说明: 请将10.25 + 17 - 13.2 / 7的结果,设定给变量kk,并转换成AutoLISP 的表达式
解法技巧A:
1:运用『二分法、加括号』:(10.25 + 17) - (13.2 / 7)
2:操作数往前提: kk = (- (10.25 + 17) (13.2 / 7))
3:操作数再往前提:kk = (- (+ 10.25 17) (/ 13.2 7))
4:转换完成: (setq kk (- (+ 10.25 17) (/ 13.2 7)))
解法技巧B:
1:运用『二分法、加括号』:(10.25 + (17 - (13.2 / 7)))
2:操作数往前提: kk = (+ 10.25 (17 - (13.2 / 7)))
3:操作数再往前提:kk = (+ 10.25 (- 17 (/ 13.2 7)))
4:转换完成: (setq kk (+ 10.25 (- 17 (/ 13.2 7))))
规则5:以档案型态存在的AutoLISP程序(ASCII档案),其扩展名必须是.LSP
规则6:撰写的环境,只要是一般的文书编辑软件,可编辑 ASCII 档案者都适用
如:PE2、PE3、DW3、书中仙、汉书、EDIT、记事本....等
规则7:以 defun 功能函数定义新的指令或新的功能函式 (注:自变量及区域变量可省略)
程序结构型态:(defun 函式名称(自变量/区域变量)
: :
: : 程序内容
: :
)
规则8:新定义的功能函式名称,若为『C:函式名』,则此函式可为 AutoCAD 新指令
(注:自变量及区域变量可省略)
程序结构型态: (defun C:KK(自变量/区域变量)
: :程序内容
: :
: :
)
则加载此 LISP 程序后,可在 指令: 后直接键入新定义的 KK 指令
规则9: 加载AutoLISP程序的作法:指令:后直接键入 (load "LISP主檔名")
注:load 与字符串间的空格,可有可无
注:load 与双引号间的空格,可有可无 (load"LISP主檔名")
范例: 在 c:\lsptools 目录下有一LISP程序tt.lsp,而您目前的工作目录在c:\dwg下
· 若『环境设定』之『支持档案搜寻路径』有指定到c:\lsptools目录,则欲使用加载tt.lspà 指令:后键入 (load "tt") 即可
· 若『环境设定』之『支持档案搜寻路径』无指定到c:\lsptools目录,则键入 (load"tt") 后,会出现错误讯息如下:
无法开启「tt.lsp」做输入错误: 加载失败(LOAD "tt")*取消*
此时您可键入:
指令:(load "c:\\lsptools\\tt") 或
指令:(load "c:"/lsptools/tt)
不可键入: (load "c:\lsptools\tt")
因为『\』在 AutoLISP 结构语法中已经用于『跳脱码控制』了
规则10:AutoLISP 程序中,在『分号 ;』后的内容均为批注,程序不处理,适时的增加批注,将使程序更具可看性、学习性及完整性
范例: pp.lsp 内容如下:
;本程序功能可快速画门、窗
;设计者:QQ博士
;版权所有,欢迎使用
(defun c:pp()
: :
; 以下为画门子程序
: :
; 以下为画窗子程序,
: :
: :
)
规则11:AutoLISP 最常用的变量型态是『整数』、『实数』、『字符串』、『点串行』四种,变量的型态依据设定值而自动定义,变量会一直储存该值,直到被重新设定值或绘图结束自动消失
规则12:以 setq 功能函数设定变量值 (setq 变量名称 设定值)
范例:
(setq a 100) ;变量 a 值设定成整数 100
(setq b 123.56) ;变量b值设定成实数123.56
(setq c "Good morning!!!") ;变量 c 值设定成字符串
(setq pt1 (getpoint "Enter POINT:")) ;变量 pt1 值设定成点串行
(setq pt2 (list a b))
;此时,a值是100,b值是123.56变量pt2值设定成点串行(100 123.56)
(setq pt3 '(297 210)) ;变量 pt3 值设定成点串行 (297 210)
注意: 直接设定成点串行时,不能省略单引号『'』否则会被误认 (297 210)又是一个表达式, 297是操作数而出错!
规则13:欲在 AutoCAD 的环境中,查看一变量值,指令:下键入『!变量名』即可
范例:
指令:(setq aa (+ 100 75)) 传回:175
指令:!aa 传回:175
指令:(setq pp (list 90 50)) 传回:(90 50)
指令:!pp 传回: (90 50)
指令:!ww 传回:nil 空值无设定
规则14:以(defun C:函式名(自变量 / 变量) ........)程序中,程序中的变量若在『/』右边变量内,则称为『区域变量』,否则为『整体变量』(注:在 AutoLISP 中,未赋予值的变量,其值皆响应 nil)
『区域变量』于此程序执行完毕后,其值自动消失
『整体变量』于此程序执行完毕后,其值仍然存在
范例: test.lsp 内容如下
(defun c:tt(/ sa sb sc)
(setq sa 100)
(setq sb 20)
(setq sc 10)
(setq sd (+ sa sb sc))
)
回到: 指令:键入(load"tt") 传回:c:tt
指令:tt 传回:130
指令:!sa 传回:nil (属区域变量)
指令:!sb 传回:nil (属区域变量)
指令:!sc 传回:nil (属区域变量)
指令:!sd 传回:130 (属整体变量)
--------------------------------------------------------------------------------
单元三:快速分类浏览AutoLISP功能函数(一)
一?看到以下那么多的 AutoLISP 功能函数,洋洋洒洒17大类:
1. 您第一个念头,一定惊讶怎么会那么多,您可能快吓坏了!
2. 您第二个念头,一定会想『那么多,怎么记得下来』,您可能快放弃了!
二?其实,您应该要『很兴奋』而『充满信心』的,怎么说呢?
1. 您有那么多的『大将』协助您撰写 AutoLISP 程序,当然左右又逢源,不但轻松, 而且要快乐的不得了!!!
2. 这些函数只要您先浏览有印象, 要用时,再翻查该函数,了解用途语法再加入到您的程序中就可以了!!!
3. 常用的函数,写久、用久后,自然会深深牢记脑海,想忘都很难,不常用的函数, 若硬要您记下来,相信连高手都很困难,更何况是初学的您!!!
4. 您不用再摸不着头绪了,因为您幸运的拥有了本书,就是您成功的开始!!!
--------------------------------------------------------------------------------
第一类 数学运算功能函数
项目
函数语法
传 回
1.1
(+ 数值 数值 ...)
累计实数或整数数值
1.2
(- 数值 数值 ...)
减去数值
1.3
(* 数值 数值 ...)
所有数值乘积
1.4
(/ 数值 数值 ...)
第一个数值除以第二个以后数值的商
1.5
(1+ 数值)
数值+1
1.6
(1- 数值)
数值-1
1.7
(abs 数值)
数值的绝对值
1.8
(atan 数值)
反正切值
1.9
(cos 角度)
角度的余弦值,角度值为弪度
1.10
(exp 数值)
数值的指数
1.11
(expt 基数 指数)
基数的指数值
1.12
(fix 数值)
将数值转换为整数值
1.13
(float 数值)
将数值转换为实数值
1.14
(gcd 数值1 数值2)
二数值的最大公因子
1.15
(log 数值)
数值的自然对数值
1.16
(max 数值 数值 ...)
数值中的最大值
1.17
(min 数值 数值 ...)
数值中的最小值
1.18
pi
常数p ,其值约为 3.1415926
1.19
(rem 数值1 数值2)
二数值的相除的余数
1.20
(sin 角度)
角度的正旋值,角度值为弪度
1.21
(sqrt 数值)
数值的平方根
第二类 检验 & 逻辑运算功能函数
项目
函数语法
传 回
2.1
(= 表示式1 表示式2)
比较表示式1是否等于表示式2适用数值及字符串
2.2
(/= 表示式1 表示式2)
比较表示式1是否大于等于表示式 2
2.3
(< 表示式1 表示式2)
比较表示式 1 是否 <小于 表示式 2
2.4
(<= 表示式1 表示式2)
比较表示式 1 是否 <=小于等于 表示式 2
2.5
(> 表示式1 表示式2)
比较表示式 1 是否 >大于 表示式 2
2.6
(>= 表示式1 表示式2)
比较表示式1是否大于等于表示式2
2.7
(~ 数值)
传回:数值的位not值,(1的补码)
2.8
(and 表示式1 表示式2…)
逻辑and的结果
2.9
(boole 函数 整数 整数…)
位式布尔运算
2.10
(eq 表示式1 表示式2)
比较表示式1与表示式2是否相同, 适用串行比较(实际相同)
2.11
(equal 表示式1 表示式2 [差量])
比较表示式1与表示式2是否相同, 差量可省略(内容相同)
第三类 转换运算功能函数
项目
函数语法
传 回
3.1
(angtof 字符串 [模式])
角度值的字符串转成实数
3.2
(angtos 角度 [模式 [精度]])
角度转成的字符串值
3.3
(atof 字符串)
字符串转成实数值
3.4
(atoi 字符串)
字符串转成整数值
3.5
(cvunit 数值 原始单位 转换单位)
数值转换单位后的值转换根据 acad.unt 档案
3.6
(distof 字符串 [模式])
依模式将字符串转成实数值
3.7
(itoa 整数)
整数转成字符串
3.8
(rtos 数值 模式 [精度])
实数转成字符串
3.9
(trans 点 原位置 新位置 [位移])
转换坐标系统值
第四类 串行处理功能函数
项目
函数语法
传 回
4.1
(append 串行 串行 ...)
结合所有串行成一个串行
4.2
(assoc 关键元素 联合串行)
依关键元素找寻联合串行中关系资料
4.3
(car 串行)
串行中的第一个元素通常用来求 x 坐标
4.4
(cadr 串行)
串行中的第二个元素通常用来求 y 坐标
4.5
(caddr 串行)
串行中的第三个元素通常用来求 z 坐标
4.6
(cdr 串行)
除去第一个元素后的串行
4.7
(cons 新元素 串行)
将新元素结合到串行
4.8
(foreach 名称 串行 表示式)
将串行的每一元素对应至名称再依表示式执行响应
4.9
(length 串行)
串行内的元素数量
4.10
(list 元素 元素…)
将所有元素结合成一串行
4.11
(listp 元素)
判断元素是否为一串
4.12
(mapcar 函数 串行1 串行2 ...)
将串行1、串行2、…等串行的 元素配合函数,求得新串行
4.13
(member 关键元素 串行)
依关键元素(含)以后的串行
4.14
(nth n 串行)
串行的第n个元素
4.15
(reverse 串行)
将串行元素依顺序颠倒过来的串行
4.16
(subst 新项 旧项 串行)
替换新旧串行后的串行
第五类 字符串、字符、档案处理功能函数
项目
函数语法
传 回
5.1
(ascii 字符串)
字符串第一个字符的『ASCII』码
5.2
(chr 整数)
整数所对应的 ASCII 单一字符串
5.3
(close 文件名称)
关闭档案
5.4
(open 文件名 模式)
开启档案代码,准备读取或写入资料
5.5
(read 字符串)
串行中的字符串的第一组元素
5.6
(read-char [档案代码])
经由键盘或档案中读取单一字符
5.7
(read-line [档案代码])
经由键盘或档案中读取一行字符串
5.8
(strcase 字符串 [字样])
转换字符串大小写
5.9
(strcat 字符串1 字符串2 ...)
将各字符串结合成一字符串
5.10
(strlen 字符串)
字符串构成的字符数(即字符串长度)
5.11
(substr 字符串 起始 长度)
取出子字符串
5.12
(wcmatch 字符串 格式)
T或nil,将字符串与通用字符进行比对
5.13
(write-char 数值 [档案代码])
将一ASCII字符写到档案或屏幕
5.14
(write-line 字符串 [档案代码])
将字符串写到档案或屏幕上
第六类 等待输入功能函数
项目
函数语法
传 回
6.1
(getangle [基点] [提示])
请求输入十进制角度数值,响应一弪度值提示及参考点可有可无
6.2
(getcorner 基点 [提示])
请求输入另一矩框对角点坐标
6.3
(getdist [基点] [提示])
请求输入一段距离
6.4
(getint [提示])
请求输入一整数值
6.5
(getkword [提示])
请求输入『关键词』
6.6
(getorient [基点] [提示])
请求输入十进制角度,响应一弪度值不受angbase、angdir影响
6.7
(getpoint [基点] [提示])
请求输入一个点坐标
6.8
(getreal [提示])
请求输入一实数
6.9
(getstring [提示])
请求输入一字符串
6.10
(initget [位] 字符串)
设定下次 getxxx 函数的有效输入
第七类 几何运算功能函数
项目
函数语法
传 回
7.1
(angle 点1 点2)
取得二点的角度弪度值
7.2
(distance 点1 点2)
取得二点的距离
7.3
(inters 点1 点2 点3 点4 [模式])
取得两条线的交点
7.4
(osnap 点 模式字符串)
依辅助抓点模式取得另一坐标点
7.5
(polar 基点 弪度 距离)
依极坐标法取得另一坐标点
7.6
(textbox 像素串行)
取得文字符串的二对角点坐标
第八类 像素处理功能函数
项目
函数语法
传 回
8.1
(entdel 像素名称)
删除或逆删除像素
8.2
(entget 像素名称 [应用程序串行])
取出像素名称的资料串行
8.3
(entlast)
取出图形数据中的最后一个像素
8.4
(entmake 像素串行)
建立一个新的像素串行
8.5
(entmod 像素串行)
依更新的资料串行更新屏幕上元体
8.6
(entnext [像素名称])
找寻图面中的下一个像素
8.7
(entsel [提示])
请求选取一个像素,响应包含像素名称及选点坐标的串行
8.8
(entupd 像素名称)
更新屏幕上复元体图形
8.9
(handent 图码)
图码的元体名称
8.10
(nentsel [提示])
BLOCK所含副元体像素数据串行
8.11
(nentselp [提示] [点])
BLOCK所含副元体像素数据(以4 x 4矩形表示)
--------------------------------------------------------------------------------
单元四:快速分类浏览AutoLISP功能函数(二)
第九类 选择集、符号表处理功能函数
项目
函数语法
传 回
9.1
(ssadd [像素名称] [选择集])
将像素加入选择集或建立一新选择集
9.2
(ssdel 像素名称 选择集)
将像素自选择集中移出
9.3
(ssget [模式] [点1] [点2])
取得一个选择集
9.4
(ssget "X" [过滤串行])
取得依过滤串行所指定范围的选择集
9.5
(sslenth 选择集)
计算选择集的像素个数
9.6
(ssmemb 像素名称 选择集)
响应像素名称是否包含于选择集内
9.7
(ssname 选择集 索引值)
依索引值取出选择集中的像素名称
9.8
(tblnext 符号表名称 [T])
检视符号表,有效的符号表: "LAYER"、"LTYPE"、"VIEW"、"STYLE"、"BLOCK"
9.9
(tblsearch 符号表名称 符号)
在符号表中搜寻符号
第十类 AutoCAD 相关查询、控制功能函数
项目
函数语法
传 回
10.1
(command "AutoCAD 指令" ...)
呼叫执行AutoCAD指令
10.2
(findfile 檔名)
传回:应该文件名的路径及文件名
10.3
(getfiled 标题 内定档名 扩展名 旗号)
透过标准AutoCAD档案对话DCL交谈框求得档案
10.4
(getenv "环境变量")
取得该环境变量的设定值,以字符串表示
10.5
(getvar "系统变量")
取得该系统变量的设定值,以字符串表示
10.6
(setvar "系统变量" 值)
设定该系统变量的值
10.7
(regapp 应用类项)
将目前的AutoCAD图形登记为一个应用程序名称
第十一类 判断式、循环相关功能函数
项目
函数语法
传 回
11.1
(if <比较式> <表示式1> [表示式2])
检算比较式结果,如果为真,执行<表示式1>否则,执行<表示式2>
11.2
(repeat 整数 [<表达式> <表达式> ...])
重复执行<整数>次数
11.3
(while 标题 内定档名 扩展名 旗号)
透过标准 AutoCAD 档案对话DCL交谈框求得档案
11.4
(cond "环境变量")
取得该环境变量的设定值,以字符串表示
11.5
(progn 表达式1 表达式2 ...)
连结其内的表达式为一组,常用于配合if、cond等函数
第十二类 函数处理、定义、追踪 & 错误处理功能函数
项目
函数语法
传 回
12.1
(*error* 字符串)
程序错误时的警示讯息
12.2
(alert 字符串)
以交谈框式显示出警告字符串
12.3
(apply 功能函数 串行)
将功能函数与串行结合后执行
12.4
(defun 名称 自变量串行 表示式 ...)
自定函数或子程序
12.5
(eval 表示式)
传回:表示式的执行结果
12.6
(exit)
强制退出目前的应用程序
12.7
(lambda 自变量 表示式)
定义未具名的函数
12.8
(progn 表达式1 表达式2 ...)
连结其内的表达式为一组,常用于配合if、cond等函数
12.9
(quit)
强制退出目前的应用程序
12.10
(tablet 代码 [列1 列2 列3 方向])
取用或建立对数字板的校调
12.11
(trace 函数…)
对函数设定追踪旗号,辅助除错
12.12
(untrace 函数…)
对函数设定解除追踪旗号
第十三类 显示、打印控制功能函数
项目
函数语法
传 回
13.1
(graphscr)
作图环境切换到图形画面
13.2
(grclear)
暂时清除模前的屏幕画面
13.3
(grdraw 起点 终点 颜色 [亮显])
暂时性的画出一条线
13.4
(grread [追踪])
由输入设备读取追踪值
13.5
(grtext 位置 字符串 [亮显])
将字符串显示在状态列或屏幕菜单上
13.6
(grvecs 向量串行 [转置矩阵])
暂时性的画出多条线
13.7
(menucmd 字符串)
提供在AutoLISP中呼叫各菜单
13.8
(prin1 [表示式 [档案代码])
将表示式打印于命令区或已开启的档案,句柄字符则以"\" 为前缀展开
13.9
(princ [表示式 [档案代码])
除句柄字符则不以 "\" 为前缀展开外其余同prin1
13.10
(print [表示式 [档案代码])
除表示式会往下一新行列出,及一空格外其余同prin1
13.11
(prompt 讯息)
将讯息显示于屏幕的命令区,并随后响应一个nil讯息
13.12
(redraw [像素名称 [模式]])
重绘整张图或依像素名称重绘该图形
13.13
(terpri)
在屏幕上显示新列
13.14
(textscr)
作图环境切换到文字画面
13.15
(textpage)
清除文字画面文字类似DOS的cls指令
13.16
(vports)
传回:窗口组态串行
第十四类 符号、元素、表示式处理功能函数
项目
函数语法
传 回
14.1
(atom 元素)
如果元素不是串行,响应 T,否则为 nil
14.2
(atoms-family 格式 [符号串行])
传回:一组已定义函数的符号串行
14.3
(boundp 表示式)
传回:T或nil,响应表示式是否有值存在
14.4
(minusp 元素)
传回:T 或 nil,元素是否为负值
14.5
(not 元素)
传回:T 或 nil,判定元素是否为 nil
14.6
(null 元素)
传回:T或nil判定元素是否被赋予nil值
14.7
(numberp 元素)
传回:T或nil,元素是否为整数或实数
14.8
(... '表示式)
响应表示式未检算前状态
14.9
(quote 表示式)
响应表示式未检算前状态,同『'』功能
14.10
(set 符号 表示式)
将表示式结果设定给带单引号 ' 符号
14.11
(setq 符号1 表示式1 [符号2 表示式2]...)
设定表示式结果给各符号
14.12
(type 元素)
传回:元素的资料型态
143.13
(zerop 元素)
传回:T 或 nil,元素是否为 0 值
第十五类 ADS、AutoLISP 加载与释放函数
项目
函数语法
传 回
15.1
(ads)
传回:目前加载ADS程序串行
15.2
(ver)
传回:目前AutoLISP版本字符串
15.3
(load LSP檔名 [加载失败])
加载AutoLISP档案(*.lsp)
15.4
(arxload <应用程序名称> [错误响应])
加载一个ARX应用程序文件
15.5
(arxunload <应用程序名称> [错误响应])
释放ARX应用程序文件
15.6
(autoarxload <文件名称> <指令定义>)
加载一个关连式的ARX檔
15.7
(autoload ADS 定义的函数 & 指令)
加载一个关连式的AutoLISP檔
15.8
(autoxload <文件名称> <指令定义>)
加载一个关连式的ADS檔
15.9
(xload 应用程序 [出错处理])
加载ADS应用程序
15.10
(xunload 应用程序 [出错处理])
释放ADS应用程序
第十六类 内存空间管理函数
项目
函数语法
传 回
16.1
(alloc 数值)
以节点数值设定区段大小
16.2
(expand 数值)
以区段数值配置节点空间
16.3
(gc)
强制收回废内存
16.4
(mem)
显示目前的内存使用状态
16.5
(vmon)
释放ADS应用程序
16.6
(xdroom 像素名称)
传回像素延伸资料允用得内存空间
16.7
(xdsize 串行)
传回像素延伸资料所占用的内存空间
第十七类 ARX 定义的函数
项目
函数语法
传 回
17.1
(acad_colordlg 颜色码 旗号)
显示出标准AutoCAD颜色选择交谈框
17.2
(acad_helpdlg 求助文件名 主题)
显示出标准 AutoCAD 求助交谈框
17.3
(acad_strlsort 串行)
作串行排序
--------------------------------------------------------------------------------
单元五:轻松快速的掌握AutoLISP设计技巧
一、AutoLISP 程序设计的四个步骤:
1.第一步骤:产生写程序的动机、预期目标
2.第二步骤:构思程序流程、所需之LISP功能函数、相关变量订定&提示讯息
3.第三步骤:利用文书软件 (如记事本) 撰写xxx.lsp程序
4.第四步骤:回到AutoCAD下,加载AutoLISP程序以 (load"LSP主檔名") 或 (load "LSP主檔名")
5.第五步骤:执行新的 AutoLISP 指令
二、透过简单范例全程演练AutoLISP:
1.第一步骤:动机、预期目标
如图: 希望能在输入『左下角点』、『矩形宽』、『矩形高』后,自动的将图形依所给的条件画出,如此一来,尔后画这个图就轻松愉快了!
2.第二步骤:构思程序相关变量订定(如下图)
· 定出程序名为 pbox.lsp
· 构思程序流程、相关变量:变量名称可自行设定(如 pa、ww、hh、pb、pc、pd、mp1、mp2、mp3、mp4),掌握三个原则:
不可重复
好记不会混淆
适时的以分号『;』加上批注
(defun c:pbox()
;以下 pa、ww、hh 值须由使用者输入
(setq pa (请求输入左下角点))
(setq ww (请求输入矩形宽度实数值))
(setq hh (请求输入矩形高度实数值))
;以下pb、pc、pd值须由程序依据pa、ww、hh求出
(setq pb (依据相对极坐标法求出pb点坐标值))
(setq pc (依据相对极坐标法求出pc点坐标值))
(setq pd (依据相对极坐标法求出pd点坐标值))
;以下依据 pa、pb、pc、pd 点画矩形
(以pline指令画出矩形)
;以下mp1、mp2、mp3、mp4值须由程序依据pa、ww、hh
;& pb、pc、pd 值求出
(setq mp1 (求出 mp1 点坐标值))
(setq mp3 (求出 mp3 点坐标值))
(setq mp2 (求出 mp2 点坐标值))
(setq mp4 (求出 mp4 点坐标值))
;以下依据 mp1、mp2、mp3、mp4 点画出二条线
(以 line 指令画出 mp1 到 mp3 的线)
(以 line 指令画出 mp2 到 mp4 的线)
)
本程序所需的 AutoLISP功能函数及其用法
(getpoint [基点] [提示]) <-- 请求输入一个点坐标
(getreal [提示]) <-- 请求输入一实数
(polar 基点 弪度 距离) <-- 依极坐标法取得另一坐标点
其中『弪度值』之转换为:
十进制角度
弪度值
十进制转弪度公式
0度
0
0
90度
1/2p
(/ pi 2) 或 (* pi 0.5)
180度
p
pi
270度
2/3p
(* pi 1.5)
N度
p *N/180
(* pi (/ n 180))
(command "AutoCAD 指令" ...) <--呼叫执行 AutoCAD 指令
注意: 指令及其副选项皆要用双引号处理
假设 pa、pb、pc、pd 皆为变量,其值为点坐标
正确: (command "pline" pa pb pc pd "c")
错误: (command pline pa pb pc pd c)
原因: 指令 pline 及其副选项 c 皆没用双引号括住
错误: (command "pline" pa pb pc pd c)
原因: 副选项c (代表 close) 没用双引号括住,会被误认为是
AutoLISP的变量名,但事实又没有 c 这个变量
错误:(command "pline" "pa" "pb" "pc" "pd" "c")
原因:变量 pa、pb、pc、pd 不须用双引号括住
注意:副选项中,若使用 "" ,连续二个双引号,代表按 [ENTER] 键
若想画一条 pa 到 pc 的 LINE & 一条 pb 到 pd 的 LINE
正确: (command "line" pa pc "")
(command "line" pb pd "")
错误: (command "line" pa pc)
(command "line" pb pd)
其它相关接近的功能函数...
(getdist [基点] [提示])?请求输入一段距离
(getint [提示]) ?请求输入一整数值
(getcorner 基点 [提示]) ?请求输入另一矩框对角点坐标
(car 串行) ?传回:串行中的第一个元素通常用来求x坐标
(cadr 串行) ?传回:串行中的第二个元素通常用来求 y 坐标
(caddr 串行) ?传回:串行中的第三个元素通常用来求z坐标
3.第三步骤:利用 PE2、CE 或记事本,撰写 PBOX.LSP 程序并储存到 C:\LISPTOOL 目录下!!!
(defun c:pbox()
;以下 pa、ww、hh 值须由使用者输入
(setq pa (getpoint "Enter Left/Low Point:"))
(setq ww (getreal "Width:"))
(setq hh (getreal "Height:"))
;以下pb、pc、pd值须由程序依据pa、ww、hh求出
(setq pb (polar pa 0 ww))
(setq pc (polar pb (/ pi 2) hh))
(setq pd (polar pc pi ww))
;以下依据 pa、pb、pc、pd 点画矩形
(command "pline" pa pb pc pd "c")
;以下mp1、mp2、mp3、mp4值须由程序依据pa、ww、hh
;& pb、pc、pd 值求出
(setq mp1 (polar pa 0 (/ ww 2)))
(setq mp2 (polar pb (/ pi 2) (/ hh 2)))
(setq mp3 (polar pd 0 (/ ww 2)))
(setq mp4 (polar pa (/ pi 2) (/ hh 2)))
;以下依据 mp1、mp2、mp3、mp4 点画出二条线
(command "line" mp1 mp3 "")
(command "line" mp2 mp4 "")
)
4.第四步骤:回到 AutoCAD 下,加载 AutoLISP 程序
若您的AutoCAD『环境设定』中『支持文件搜寻路径』有加上 c:\lisptool,则您可轻松加载 pbox.lsp 程序
指令:(load"pbox") 传回:c:pbox
或 指令:(load "pbox") 传回:c:pbox
或 指令:(load "pbox.lsp") 传回:c:pbox
若您的AutoCAD『环境设定』中『支持文件搜寻路径』并未加上 c:\lisptool,
则您加载 pbox.lsp 程序时,须包含程序所在路径:
错误的加载:指令:(load "pbox")
会出现:无法开启「pbox.lsp」做输入
错误: 加载失败
(LOAD "pbox")
*取消
正确的加载方式:
指令:(load "c:/lisptool/pbox") 传回:c:pbox
或:指令:(load "c:\\lisptool\\pbox") 传回:c:pbox
5.第五步骤:执行新的 AutoLISP 指令
指令:pbox <-- 成功加载后,直接键入 pbox 指令
Enter Left/Low Point: <-- 请给一左下角点
Width: <-- 给一实数当宽度,例如100
Hieght: <-- 给一实数当高度,例如50
指令:nil
指令
三、PBOX.LSP 程序产生的问题 & 改良
1. 原程序虽是成功的加载执行了,但却有以下几点小问题:
问题1:给完左下角点后,『Width:』及『Height:』提示却在同一行出现,应该一个提示各别一行才好???
ANS:很简单,只要做如下的改变,加入『\n』即可!!!
(setq ww (getreal "Width:"))à (setq ww (getreal "\nWidth:"))
(setq hh (getreal "Height:"))à (setq hh (getreal "\nHeight:"))
问题2:希望给宽度及高度时,也能直接在屏幕上拉一段距离代替???
ANS:很简单,只要做以下的函数变动即可!!!
将 (setq ww (getreal "\nWidth:"))
改成 (setq ww (getdist pa "\nWidth:")) ? pa为参考基准点
将 (setq hh (getreal "\nHeight:"))
改成 (setq hh (getdist pa "\nHeight:")) ? pa为参考基准点
问题3:给完宽度及高度值后,开始画出所要的图形,可是指令操作过程却也跟着在『指令:』下一一配合出现着,不但影响速度,也没有实质的意义,如何改善?
ANS:很简单,只要在程序一开始加入如下一行即可改善:
(setvar "cmdecho" 0) ? 设定变量cmdecho=0关闭指令响应
问题4:画完所要的图形过程中,画面出现了小十字点,还得用redraw指令清除,该如何使其不出现,但又不影响正常绘图设定呢??? (R14环境blipmode内定值为0)
ANS:很简单,只要在程序一开始加入 (setvar "blipmode" 0) 即可有效压抑小十字虚点出现!但须在程序结束前恢复设定 (setvar "blipmode" 1) ,才不会影响正常绘图设定
问题5:全部过程执行完后,在『指令:』后却出现了空响应 nil,如何消除呢???
指令:pbox
Enter Left/Low Point:
Width:
Hieght:
指令:nil ? 就是这一行
指令
ANS:很简单,只要在程序结束前,加入一行 (prin1) 即可
问题6:程序确认无误后,想将所有变量均处理成『区域变量』,以免占据内存
ANS:很简单,只要做如下的改变即可将 (defun c:pbox()
改成 (defun c:pbox(/ pa pb pc pd ww hh mp1 mp2 mp3 mp4)
问题7:希望在 (load "pbox") 程序的响应讯息能有更多样的变化
ANS:很简单,原响应是 c:pbox,请在程序结束后,再加入二列:
(prompt "********** << C:PBOX >> **********")
(prin1)
2. 改良后完整 PBOX.LSP 程序的全貌:
(defun c:pbox(/ pa pb pc pd ww hh mp1 mp2 mp3 mp4)
(setvar "cmdecho" 0)
(setvar "blipmode" 0)
;以下 pa、ww、hh 值须由使用者输入
(setq pa (getpoint "Enter Left/Low Point:"))
(setq ww (getdist pa "\nWidth:"))
(setq hh (getdist pa "\nHeight:"))
;以下pb、pc、pd值须由程序依据pa、ww、hh求出
(setq pb (polar pa 0 ww))
(setq pc (polar pb (/ pi 2) hh))
(setq pd (polar pc pi ww))
;以下依据 pa、pb、pc、pd 点画矩形
(指令 "pline" pa pb pc pd "c")
;以下mp1、mp2、mp3、mp4值须由程序依据pa、ww、hh
;& pb、pc、pd 值求出
(setq mp1 (polar pa 0 (/ ww 2)))
(setq mp2 (polar pb (/ pi 2) (/ hh 2)))
(setq mp3 (polar pd 0 (/ ww 2)))
(setq mp4 (polar pa (/ pi 2) (/ hh 2)))
;以下依据 mp1、mp2、mp3、mp4 点画出二条线
(指令 "line" mp1 mp3 "")
(指令 "line" mp2 mp4 "")
(prin1)
)
(prompt "********** << C:PBOX >> **********")
(prin1)
四、本章结语:
· 经由简单的 PBOX.LSP 程序设计全程演练,从『产生动机、预期目标』à 『构思程序流程、相关变量订定』à 『撰写程序』à 『加载程序』à 『执行PBOX指令』à『改良 PBOX.LSP』
· 相信您已能更了解 AutoLISP 是怎么回事了,短短的十几行,能做的事却不少,一路循序渐进练习下来,您应该觉得一点儿也不吃力、『游刃有余』才对,果真如此,那恭喜您,『好戏还在后头』,还有体力的话,就继续『征服下一章』吧!!!
· 若您仍觉得有点『迷迷糊糊』,那就休息一下,配合复习第二章『学好AutoLISP的关键、基本结构与语法』再好好的把第四章『看』&『做』个明白,相信有心成为AutoCAD高手的您,一定不会那么容易就『被十几行打败』的!!!
--------------------------------------------------------------------------------
单元六:像素数据的取得与活用技巧(一)
一.像素数据串行的重要性:
· 您可知您所绘制的每一个AutoCAD元体 (如LINE、CIRCLE、ARC、TEXT、BLOCK、POLYLINE、DIMENSION...) 均有其专属的资料串行!!!
· 没错以LIST指令即可查询出来,显示于屏幕上
· 但是该如何透过 AutoLISP 功能去选取、取得、修改、更新资料呢??? 该如何去有效活用呢???
· 别急就是本单元的学习重点!!!
· 请注意本章节非常重要,务必要求透彻了解!!!
二、重要像素资料应用相关的功能函数介绍:
· (entsel [提示]) 请求选取一个像素,响应包含像素名称及选点坐标的串行
· (car 串行) 传回:串行中的第一个元素,通常用来求x坐标
· (cadr 串行)传回:串行中的第二个元素,通常用来求y坐标
· (caddr 串行)传回:串行中的第三个元素,通常用来求z坐标
· (cdr 串行) 传回:除去第一个元素后的串行
· (entlast):取出图形数据中的最后一个像素
· (entget 像素名称 [应用程序串行]):取得像素名称的资料联合串行
· (assoc 关键元素 联合串行) :依关键元素找寻联合串行中关系资料
· (cons 新元素 串行) 传回:将新元素结合到串行,常用于产生『点对串行』
· (subst 新项 旧项 串行) 传回:替换新旧串行后的串行
· (entmod 像素串行) 依更新的资料串行更新屏幕上元体
· (list 元素 元素…) 传回:将元素结合成一串行
三、像素数据联合串行取得技巧与群码分析:
1.基础准备动作:请开一张新图,并建立二个新层STR、TXT,颜色分别为红色(red)、绿色 (green)
· 首先在STR层画一条线
指令: LINE
起点: 15,10
下一点: 50,40
下一点: (按[Enter]结束)
· 在STR层画一个圆
指令: CIRCLE
CIRCLE 三点(3P)/二点(2P)/相切,相切,半径(T)/<中心点>: 60,15
直径(D)/<半径>: 12.5
· 在TXT层写几个字AutoCAD
指令: DTEXT
对正(J)/字型(S)/<起点>: (选取文字的位置点)
高度 <2.5000>: 8
旋转角度 <0>:0
文字: AutoCAD
文字: (按[Enter]结束)
图标:
2. 在AutoCAD的Command:下练习取得像素数据串行
· 练习函数 entsel、car、cdr、entget
指令: (setq en1 (entsel))
选取对象: (选取圆)
传回一串行: (<像素名称: 2940518> (67.604 24.5166 0.0))
其中<像素名称: 2940518> <==像素名称
(67.604 24.5166 0.0) <==选点坐标
指令: (car en1)
传回: <像素名称: 2940518> <==串行的第一个元素
指令: (cadr en1)
传回: (67.604 24.5166 0.0) <==串行的第二个元素
指令: (setq en1_data (entget (car en1)))
传回『圆的联合资料串行』:
((-1 . <像素名称: 2940518>) (0 . "CIRCLE") (5 . "23")
(100 . "AcDbEntity") (67 . 0) (8 . "STR") (100 . "AcDbCircle")
(10 60.0 15.0 0.0) (40 . 12.5) (210 0.0 0.0 1.0))
其中各子串行的第一个元素均为『群码』,各代表不同对应资料
指令: (setq en2 (entsel))
选取对象: (碰选线)
传回一串行: (<像素名称: 2940500> (30.5626 23.5743 0.0))
指令: (setq en2_data (entget (car en2)))
传回『线的联合资料串行』:
((-1 . <像素名称: 2940500>) (0 . "LINE") (5 . "20")
(100 . "AcDbEntity") (67 . 0) (8 . "STR") (100 . "AcDbLine")
(10 15.0 10.0 0.0) (11 50.0 40.0 0.0) (210 0.0 0.0 1.0))
指令:(setq en3 (entsel))
选取对象: (碰选文字)
传回一串行: (<像素名称: 2940520> (45.7833 50.3614 0.0))
指令: (setq en3_data (entget (car en3)))
传回『文字的联合资料串行』:
((-1 . <像素名称: 2940520>) (0 . "TEXT") (5 . "24")
(100 . "AcDbEntity") (67 .0) (8 . "TXT") (100 . "AcDbText")
(10 10.0 50.0 0.0) (40 . 8.0) (1 . "AutoCAD") (50 . 0.0) (41 . 1.0)
(51 . 0.0) (7 . "STANDARD") (71 . 0) (72 . 0) (11 0.0 0.0 0.0)(210 0.0 0.0 1.0)
(100 . "AcDbText") (73 . 0))
3. 联合资料串行中各子串行群码分析说明:
您可以在 指令:下键入 !en1_data或 !en2_data或 !en3_data分别查看圆、线、文字的联合资料串行,您将会发现 => 不同的元体类别,其联合资料串行也不一样
圆的联合资料串行en1_data
(-1 . <像素名称: 2940518>)
群码-1对应『像素名称』
(0 . "CIRCLE")
群码0对应『像素类别』
(5 . "23")
群码5对应『处理码』
(100 . "AcDbEntity")
群码100对应『子类别』
(67 . 0)
群码 67对应『模型空间』
(8 . "STR")
群码8对应『图层名称』
(100 . "AcDbCircle")
群码100对应『子类别』
(10 60.0 15.0 0.0)
群码10对应『圆心坐标』
(40 . 12.5)
群码40对应『半径值』
(210 0.0 0.0 1.0)
群码210对应『像素挤出方向』
线的联合资料串行en2_data
(-1 . <像素名称: 2940500>)
群码-1对应『像素名称』
(0 . "LINE")
群码0对应『像素类别』
(5 . "20")
群码5对应『处理码』
(100 . "AcDbEntity")
群码100对应『子类别』
(67 . 0)
群码 67对应『模型空间』
(8 . "STR")
群码8对应『图层名称』
(100 . "AcDbLine")
群码100对应『子类别』
(10 15.0 10.0 0.0)
群码10对应『线起始点坐标』
(11 50.0 40.0 0.0)
群码11对应『线终止点坐标
(210 0.0 0.0 1.0)
群码210对应『像素挤出方向』
文字的联合资料串行 en3_data
(-1 . <像素名称: 2940520>)
群码-1对应『像素名称』
(0 . "TEXT")
群码0对应『像素类别』
(5 . "24")
群码5对应『处理码』
(100 . "AcDbEntity")
群码100对应『子类别』
(67 . 0)
群码67对应『模型空间』
(8 . "TXT")
群码8对应『图层名称』
(100 . "AcDbText")
群码100对应『子类别』
(10 10.0 50.0 0.0)
群码10对应『插入点』
(40 . 8)
群码40对应『字高』
(1 . "AutoCAD")
群码1对应『文字内容』
(50 . 0.0)
群码50对应『旋转角度』
(41 . 1.0)
群码41对应『宽度比例系数』
(51 . 0.0)
群码51对应『倾斜角』
(7 . "STANDARD")
群码7对应『字型名称』
(71 . 0)
群码71对应『镜设方向』
(72 . 0)
群码72对应『水平对齐设定』
(11 0.0 0.0 0.0)
群码11 对应『对齐点』
(210 0.0 0.0 1.0)
群码210对应『像素挤出方向』
(100 . "AcDbText")
群码100对应『子类别』
(73 . 0)
群码73 对应『水平对齐设定』
4. 由以上可看出,元体资料串行有些『群码』是共通的 (如 -1、0、8、210) 有些『群码』是因元体而异的(如 10、40),有些『群码』是某些元体特有的(如 en3_data 资料串行就比 en1_data & en2_data 资料串行来的多)
注意1:往后练习撰写 AutoLISP 程序中,若对各元体与群码的对应有疑问或不清楚时,请随时查看『附录 C』有关详细的群码表分析!!!
注意2:子串行中间有一点『?』隔开二元素,我们称为『点对串行』,点对串行要特别注意的是『第二个元素取得,要用cdr函数』,而非cadr函数!若要产生新的『点对串行』,可用cons函数完成.如:
(cons 1 “ABC”) 响应 (1 . “ABC”)
四、像素数据修改与更新技巧:
1.像素数据串行修改 & 更新四步骤:
步骤一:用 entget 函数取得元体数据串行,如上例中 en1_data、en2_data、en3_data
步骤二:用assoc函数依『群码值』找寻取得欲修改的旧『子串行』,新的子串行可以用 cons 函数去产生
步骤三:用 subst 函数将数据串行中的新、旧子串行替换
步骤四:用 entmod 函数更新的资料串行,同时自动更新屏幕上像素
2.在AutoCAD的『指令:』下做基本像素数据修改&更新练习:
请将上例中,圆的半径修改为23.8过程如下:
指令:!en1_data
传回:
((-1 . <像素名称: 2940518>) (0 . "CIRCLE") (5 . "23")(100 . "AcDbEntity") (67 . 0) (8 . "STR") (100 . "AcDbCircle") (10 60.0 15.0 0.0) (40 . 12.5) (210 0.0 0.0 1.0))
指令: (setq oldr (assoc 40 en1_data))
传回:(40 . 12.5) <==群码40为索引值的子串行
指令:(setq newr (cons 40 23.8))
传回:(40 . 23.8)
指令:(setq en1_data (subst newr oldr en1_data))
响应:
((-1 . <像素名称: 2940518>) (0 . "CIRCLE") (5 . "23")(100 . "AcDbEntity") (67 . 0) (8 . "STR")
(100 . "AcDbCircle") (10 60.0 15.0 0.0) (40 . 23.8) (210 0.0 0.0 1.0))
数据串行已被修改成功了,但是画面上像素并未更新???
指令: (entmod en1_data) <==大功告成,画面上的圆也更新了!!!
--------------------------------------------------------------------------------
单元七:像素数据的取得与活用技巧(二)
五、范例练习:
范例一:请撰写一个CHGRAD.LSP,用来修改圆半径,此程序的执行过程要求如下:
· 指令: CHGRAD
· 选取已知圆:碰选画面上已存在的圆
· 自动显示该旧圆半径值于指令区
· 新半径:要求输入一半径值 new_rr
程序内容解答:
(defun c:chgrad()
(setvar "cmdecho" 0 ;指令执行过程不响应
;;;;以下为 INPUT 像素选取
(setq en (entsel "选取已知圆:")) ;要求碰选一个圆
;;;;以下为像素资料&半径资料取得
(setq en_data (entget (car en))) ;取得元体资料串行
(setq old_rad_list (assoc 40 en_data));取得半径子串行
(setq old_rr (cdr rad_list)) ;取得旧有半径
(princ “\n旧半径=”)(princ old_rr) ;显示该旧圆半径值于指令区
;;;;以下为新半径输入&像素资料新旧半径更替
(setq cenpt (cdr (assoc 10 en_data))) ;一口气取得圆之圆心
(setq new_rr (getdist cenpt "New Radius:"));要求输入一半径值
(setq new_rad_list (cons 40 new_rr)) ;产生新半径子串行
(setq en_data (subst new_rad_list old_rad_list en_data)) ;新旧交替
(entmod en_data) ;依新像素资料自动更新圆半径
(prin1)
)
(prompt "*************** << C:CHGRAD >> *****************")
(prin1)
程序执行:(请先在画面上任意的画一些圆)
指令: (load"chgrad")
响应: *************** << C:CHGRAD >> *****************
指令: CHGRAD
选取已知圆: (碰选画面上已有的圆)
新半径:20 ( 输入一半径值)
范例二: 请撰写一个MCIR.LSP,当碰选画面上的LINE时,会在该线的中点(Midpoint)产生一个圆,此程序的执行过程要求如下:
· 指令: MCIR
· Select a LINE:碰选画面上已有的线
· Circle Radius:要求输入一半径值MR (可给整数、实数或拉一段距离)
· 自动的在该线的中点画出一个半径值为MR的圆
该如何设计MCIR.LSP呢???
解题关键:先取得线的二端点坐标pt1(px1 py1) & pt2(px2 py2),那二点的中点坐标 mpt(mx my)就用数学几何公式求得
mx = (px1 + px2)/2
my = (py1 + py2)/2
程序内容解答:
(defun c:mcir()
(setvar "cmdecho" 0) ;指令执行过程不响应
(setq en (entsel "Select a LINE:")) ;要求碰选一条线
(setq en_data (entget (car en))) ;取得元体资料串行
;******************** 求得 pt1 & px1、py1 *********************
(setq pts (assoc 10 en_data)) ;取得群码10的子串行
(setq pt1 (cdr pts)) ;取得起点pt1坐标
(setq px1 (car pt1)) ;取得pt1坐标的x值
(setq py1 (cadr pt1)) ;取得pt1坐标的y值
;******************** 求得 pt2 & px2、py2 ***********************
(setq pte (assoc 11 en_data)) ;取得群码11的子串行
(setq pt2 (cdr pte)) ;取得终点pt2坐标
(setq px2 (car pt2)) ;取得pt2坐标的x值
(setq py2 (cadr pt2)) ;取得pt2坐标的y值
;***************** 求得 mx & my 并结合成 mpt ****************
(setq mx (/ (+ px1 px2) 2)) ;求得mx值
(setq my (/ (+ py1 py2) 2)) ;求得my值
(setq mpt (list mx my)) ;结合mx & my成mpt点
;******************** Input <mr> & Finish ************************
(setq mr (getdist mpt "Circle Radius:"));要求输入半径值
(command "circle" mpt mr) ;完成中点画圆
(prin1)
)
(prompt "*************** << C:MCIR >> *****************")
(prin1)
程序执行:(请先在画面上任意的画一些线)
指令: (load"mcir")
响应: *************** << C:MCIR >> *****************
指令: MCIR
Select a LINE: (碰选画面上已有的线)
Circle Radius:20 (输入半径20)
注意:
1. 变量值查询:您若想进一步查询执行后变量值,没问题!!!请搭配à 惊叹号『!』+『变量名』输入在『指令:』后如!en、!en_data、!pts、!pt1、!px1、!py1、!pte、!pt2、!px2、!py2 、!mx、!my、!mpt、!mr
2. 以上程序中所用到的变量,读者皆可自行命名,以方便、好记、不会混淆为原则
3. 若不加上最后两行
(prompt "*************** << C:MCIR >> *****************")
(prin1)
则程序在加载后,将只响应 c:mcir
4. 建议读者们养成加入最后两行的习惯,以免未来程序越来越大,加载程序后,根本无从知道该如何执行此LISP程序,因为程序内可能有好几个C:XX 的指令函数,也可能有很多子程序!!!
范例三:请撰写一个 CPOLY5.LSP,碰选CIRCLE后,自动产生一个圆内接正五边形,此程序的执行过程要求如下:
· 指令: cpoly5
· Select CIRCLE:碰选画面上已有的圆
· 自动产生一个内接正五边形,OK!
该如何设计CPOLY5.LSP呢???
解题关键:
· 先取得圆的圆心点坐标cenpt & 半径rr
· 仿真polygon完成内接正五边形的过程:
指令:POLYGON
边数 <4>: 5
边缘(E)/<多边形的中心点>: (选一点为正多边形中心)
内接或外切于圆 (内接(I)/外切(C)) <I>:I
圆的半径: (给一个半径值)
程序内容解答:
(defun c:cpoly5()
(setvar "cmdecho" 0) ;指令执行过程不响应
(setq en (entsel "Select CIRCLE:")) ;要求碰选一个圆
(setq en_data (entget (car en))) ;取得元体资料串行
(setq cenpt (cdr (assoc 10 en_data))) ;求得圆心 cenpt
(setq rr (cdr (assoc 40 en_data))) ;求得半径 rr
(command "polygon" 5 cenpt "i" rr) ;完成圆内接正五边形
(prin1)
)
(prompt "*************** << C:CPOLY5 >> *****************")
(prin1)
程序执行:(请先在画面上任意的画一些圆)
指令:(load"cpoly5")
响应 *************** << C:CPOLY5 >> *****************
指令: CPOLY5
Select CIRCLE: (碰选画面上已有的圆)
OK! 完成一个内接正五边形
范例四:请撰写一个 CIRSCA.LSP,其内有二个可执行函数:
· CIRA碰选CIRCLE后,原CIRCLE大小自动缩为原来的1/2
· CIRB碰选CIRCLE后,原CIRCLE大小自动放大为原来的2倍
此程序的执行过程要求如下:
指令:cira
Select CIRCLE to <Scale 0.5>: (碰选画面上已有的圆)
自动产生CIRCLE 大小自动缩为原来的1/2
指令:cirb
Select CIRCLE to <Scale 2>: (碰选画面上已有的圆)
自动产生CIRCLE 大小自动放大为原来的2倍
该如何设计CIRSCA.LSP呢???
解题关键:
· 用entget函数取得圆的元体数据串行cir_data
· 用assoc函数取得群码40的半径『子串行』rad_list,并以cdr取得半径值old_r,再依此值作放大2倍或缩小一半新的半径子串行可以用cons函数结合群码40 & 新半径值
· 用subst函数将数据串行中的新、旧子串行替换
· 用 entmod 函数依更新的资料串行更新屏幕上圆
程序内容解答:
(defun c:cira()
(setvar "cmdecho" 0)
(setq cir (entsel "Select CIRCLE to <Scale 0.5>:"))
(setq cir_data (entget (car cir))) ;取得元体资料串行
(setq old_rad_list (assoc 40 cir_data)) ;取得原半径子串行
(setq old_r r(cdr rad_list)) ;求得半径old_r
(setq new_rr (* old_rr 0.5)) ;求得新半径new_r
(setq new_rad_list (cons 40 new_rr)) ;产生新半径子串行
(setq cir_data (subst new_rad_list old_rad_list cir_data))
(entmod cir_data)
(prin1)
)
(defun c:cirb()
(setvar "cmdecho" 0)
(setq cir (entsel "Select CIRCLE to <Scale 2>:"))
(setq cir_data (entget (car cir))) ;取得元体资料串行
(setq old_rad_list (assoc 40 cir_data)) ;取得原半径子串行
(setq old_r r(cdr rad_list)) ;求得半径old_r
(setq new_rr (* old_rr 2)) ;求得新半径new_r
(setq new_rad_list (cons 40 new_r)) ;产生新半径子串行
(setq cir_data (subst new_rad_list old_rad_list cir_data))
(entmod cir_data) ;画面上元体更新
(prin1)
)
(prompt "*****<< C:CIRA >> ***** << C:CIRB >>********")
(prin1)
程序执行:(请先在画面上任意的画一些圆)
指令:(load"cirsca")
响应 *****<< C:CIRA >> ***** << C:CIRB >>********
指令: cira
Select CIRCLE to <Scale 0.5>: (碰选画面上已有的圆)
OK! 完成一个缩小为 1/2 倍的圆
指令:cirb
Select CIRCLE to <Scale 2>:碰选画面上已有的圆
OK! 完成一个放大为 2 倍的圆
六、测验练习&解答,举一反三:
题目:
· 改写范例二的MCIR.LSP,让程序更精简有力??? (原程序有21行)
· 特殊解法(配合函数 OSNAP & MID 对象锁点功能)
· 而且希望问半径时,能以类似标准circle指令的半径拖动模式出现?
解答: 改写范例二的MCIR.LSP,让程序更精简有力???新程序剩下 15 行,省了 6 行
(defun c:mcir1()
(setvar "cmdecho" 0)
(setq en (entsel "Select a LINE:"))
(setq en_data (entget (car en)))
(setq pt1 (cdr (assoc 10 en_data))) ;直接取得第一点
(setq pt2 (cdr (assoc 11 en_data))) ;直接取得第二点
(setq mx (/ (+ (car pt1) (car pt2)) 2)) ;求得中点X坐标
(setq my (/ (+ (cadr pt1) (cadr pt2)) 2));求得中点Y坐标
(setq mpt (list mx my))
(setq mr (getdist mpt "Circle Radius:"));要求输入半径值
(command "circle" mpt mr) ;完成中点画圆
(prin1)
)
(prompt "*************** << C:MCIR1 >> *****************")
(prin1)
· 特殊解法(配合函数 OSNAP & MID 对象锁点功能)新程序剩下 11 行,省了 10 行
(defun c:mcir2()
(setvar "cmdecho" 0)
(setq en (entsel "Select a LINE:"))
(setq pts(cadr en)) ;选取时点选坐标
(setq mpt (osnap pts “mid”)) ;直接取得中点
(setq mr (getdist mpt "Circle Radius:"));要求输入半径值
(command "circle" mpt mr) ;完成中点画圆
(prin1)
)
(prompt "*************** << C:MCIR2 >> *****************")
(prin1)
· 再改写MCIR2.LSP à MCIR3.LSP程序而且以类似标准circle指令的半径拖动模式出现
(defun c:mcir3()
(setvar "cmdecho" 0)
(setq en (entsel "Select a LINE:"))
(setq pts (cadr en))
(setq mpt (osnap pts "mid"))
(command "circle" mpt pause) ;<<== 注意 pause 的用法
(prin1)
)
(prompt "*************** << C:MCIR3 >> *****************")
(prin1)
七、本章结语:
像素数据的取得&修改更新是AutoLISP程序设计师必备的能力,不管是新手或熟手,而熟手甚至于要具备将【常用群码对应】记在脑海本事,如此一来,才能让您的AutoLISP程序设计速度再往前推进,除了【附录C】可随时翻查外,万一没带书在身边,也千万别束手无策,别忘了在指令区常常输入以下表示式:(entget (car (entsel)))休息一下,明天再来征服下一章吧!!!
以取得像素联合数据串行,来帮您快速的对照记忆各个像素相关群码,因为下一章的【判断式&循环】是无数AutoLISP新手想不碰,又不能不碰,闻之丧胆,甚至终结新手AutoLISP程序设计生命的重要关卡,无论如何,必须请您在最清楚的头脑&最佳的体力状态下闯关,才不会搞的头昏脑胀,遍体麟伤!!!
--------------------------------------------------------------------------------
单元八:新手上路-参数设计的关键技巧
一、参数设计的重要性:
您可知 参数化的设计可大大的提身原有的绘图效率,将原本繁琐的过程化身成程序自动化产生
没 错 参数化可以让效率提升至少十倍以上,让复杂图形在瞬间完成,有如变魔术一般的神奇,让AutoCAD新手也能在用你的程序操作下,画出有模有样的图形来
但 是 AutoLISP参数设计要做的好,除了搭配下册的DCL交谈框为程序漂亮门面外,仍得具备几项关键技巧与常识,才能游刃有余的设计各种不同的参数模块图形?
别 急 深呼吸,放松心情,保持最清楚的思绪!!!
请注意 书后有相当多的精选范例,参考并熟读之,您一定能掌握其中的精髓!!
二、重要关键-熟知三角函数关系
· 熟记勾股定理-直角三角形二股平方和等于写边平方 A*A+B*B=C*C
· 熟记三角形内外角关系
1. 任意三角形内角和等于180度
2. 直角三角形另二角和等于90度
3. 正三角形的3内角街等于 60 度
4. 等腰三角形必有二个相同的内角
5. 三角形外角等于二个远内角和
· 熟记基本三角函数:
三角函数
表示式
重要等级
AutoLISP支持
Sinθ
A / C
熟记
Yes
Cosθ
B / C
熟记
Yes
Tanθ
A / B
熟记
NO
Cotθ
B / A
NO
Secθ
C/B
NO
Cscθ
C/A
NO
· 熟记三角函数之间的诀窍:
诀窍一:对边关系->对边三角函数相乘等于1 (互为倒数)
Sinθ*Cscθ=1
Cosθ*Secθ=1
Tanθ*Cotθ=1
诀窍二:邻边关系->二边函数相乘等于中间函数
Sinθ= Tanθ*Cosθ
Tanθ= Sinθ*Secθ= Sinθ*1/Cosθ=Sinθ/Cosθ
诀窍三:平方关系->斜线区三角形,上二顶点平方和等于下顶点平方
Sinθ平方+Cosθ平方=1 à Sinθ^2+Cosθ^2=1
Tanθ平方+1= Secθ平方 à Tanθ^2+1= Secθ^2
1+Cotθ平方= Cscθ平方 à 1+ Cotθ^2= Cscθ^2
诀窍四:反三角函数关系
三角函数
表示式
反求角度
反三角函数
重要等级
AutoLISP支持
Sinθ
A / C
θ
ASIN(A/C)
NO
Cosθ
B / C
θ
ASIN(B/C)
NO
Tanθ
A / B
θ
ASIN(A/B)
熟记
Yes
Cotθ
B / A
θ
ASIN(B/A)
NO
Secθ
C/B
θ
ASIN(C/B)
NO
Cscθ
C/A
θ
ASIN(C/A)
NO
三、AutoLISP三角函数&转换相关函数
1. (sin 径度角) 传回:该径度角的SIN正弦数值
2. (cos 径度角) 传回:该径度角的COS余弦数值
3. (atan 数值1 [数值2]) 传回:该数值的反正切径度值
4. (sqrt 数值) 传回:该数值的开平方根
5. (abs 数值) 传回:该数值的绝对正值
6. (strcat 字符串 字符串… ) 传回:字符串结合
7. (rtos 数值 [精确度] ) 传回:实数转换字符串&控制小数点精确度
8. (angle 点1 点2) 传回:点1至点2的径度值
9. (angtof 字符串 <模式> ) 传回:将十进制度字符串转为径度数值
10. (angtos 径度数值 <模式> <精确度> ) 传回:将径度数值依模式&精确度转为数值字符串
四、精选三角函数应用技巧范例一:
预期目标:如图,希望能在输入左下角点后,只给直角三角形的底边&斜边长后,自动绘出该直角三角形
步骤一:定出程序名称为 5test1.lsp
步骤二:构思程序流程、相关变量:
变量名称设定为 pa、pb、pc、ww、kk、hh、ang_pb、ang_pc
(defun c:5test1()
;以下 pa、ww、kk 值须由使用者输入
(setq pa (请求输入左下角点))
(setq ww (请求输入直角三角形底边长度))
(setq kk (请求输入直角三角形斜边长度))
;以下pb、pc、hh值须由程序依据pa、ww、kk求出
(setq pb (依据相对极坐标法求出右下角pb点坐标))
(setq hh (依据ww&kk值,以勾股定理求出hh值))
(setq pc (依据相对极坐标法求出左上角pc点坐标值))
;以下依据 pa、pb、pc 点画出直角三角形
(将hh 的结果响应在指令区)
(画出直角三角形)
;以下将三角形二夹角自动求出,并显示在指令区
(setq ang_pb (依据反正切求pb夹角弪度值))
(setq ang_pb (将ang_pb改推算成十进制角度值))
(setq ang_pc (依据90度减去ang_pb求得ang_pc夹角))
(将PB的夹角响应在指令区)
(将PC的夹角响应在指令区)
(prin1)
)
步骤三:撰写 5test1.lsp 并储存到 C:\LISPTOOL资料夹内
(defun c:5test1()
;以下 pa、ww、kk 值须由使用者输入
(setq pa (getpoint “请输入直角三角形左下角点:”))
(setq ww (getreal ”\n请输入直角三角形底边长度:”))
(setq kk (getreal ”\n请输入直角三角形斜边长度:”))
;以下pb、pc、hh值须由程序依据pa、ww、kk求出
(setq pb (polar pa 0 ww))
(setq hh (sqrt (- (* kk kk) (* ww ww))))
(setq pc (polar pa (/ pi 2) hh))
;以下依据 pa、pb、pc 点画出直角三角形
(princ "\n另一边hh的长度=")(princ hh)
(command “line” pa pb pc “c”) ;;;用PLINE也可以
;以下将三角形二夹角自动求出,并显示在指令区
(setq ang_pb (atan (/ hh ww)))
(setq ang_pb (* ang_pb (/ 180 pi)))
(setq ang_pc (- 90 ang_pb))
(princ "\nPB的夹角=")(princ ang_pb)(princ "度")
(princ "\nPC的夹角=")(princ ang_pc)(princ "度")
(prin1)
)
(prompt “\n << 5TEST1>>自动直角三角形绘制”)
(prin1)
步骤四:执行程序 5test1.lsp
指令: (load "5test1") <--加载程序
<< 5TEST1>> 自动直角三角形绘制 <-- 传回之讯息
指令:5test1
请输入直角三角形左下角点: <-- 请给一左下角点
请输入直角三角形底边长度: <--请给一实数 80
请输入直角三角形斜边长度: <--请给一实数 95
<除自动画出该直角三角形外,又传回以下三项讯息>
另一边hh的长度=51.2348
PB的夹角=32.6369度
PC的夹角=57.3631度
执行结果:
步骤四:程序改良&注意重点
重点1. AutoLISP 中,并无 ASIN 反正弦& ACOS反余弦函数,所以无法透过 kk & ww 求出 ang_pb 反正弦角也无法透过 kk & hh 求出 ang_pc 反余弦角
重点2. (setq ang_pb (atan (/ hh ww))) 可改写成 (setq ang_pb (atan hh ww)) 结果一样
重点3. (princ "\nPB的夹角=")(princ ang_pb)(princ "度")
(princ "\nPC的夹角=")(princ ang_pc)(princ "度")
可用 strcat 函数结合成同一字符串,改写如下
(princ (strcat "\nPB的夹角=" (rtos ang_pb) “度”))
(princ (strcat "\nPC的夹角=" (rtos ang_pc) “度”))
但需特别留意,strcat 只接受字符串格式的结合而 princ 却可响应任意型态的变量
五、精选三角函数应用技巧范例二:
预期目标:如图,希望能自动画出多个等半径圆相切,执行顺序如下:
· 输入基准点 baspt
· 输入小圆半径 rad
· 输入欲相切的等圆数量 num
· 自动绘出多个等半径圆相切
步骤一:定出程序名称为 5test2.lsp
步骤二:构思程序流程、相关变量:
变量名称设定为 baspt、rad、num、midpt、cenpt、kk、ang1、ang2
(defun c:5test2()
;以下 baspt、rad、num 值须由使用者输入
(setq baspt (请求输入基准点))
(setq rad (请求输入小圆半径))
(setq num (请求输入欲相切的小圆数量))
;只要能求得 cenpt 点,再以 array 指令配合就万事OK了
;以下ang1、kk、cenpt值须由程序依据baspt、rad、num求出
(setq ang1 (依据全圆周除以num等分,再除以2求得))
(setq kk (依据rad & sin<ang1>相除求得该值))
(setq ang2 (依据 pi/2 减去 ang1求得))
(setq cenpt (依据相对极坐标法ang2 & kk求出坐标值))
;以下依据 cenpt、num 配合环形array画出多圆相切
(自动画出多圆相切)
(prin1)
)
步骤三:撰写 5test2.lsp 并储存到 C:\LISPTOOL资料夹内
(defun c:5test2()
;以下 baspt、rad、num 值须由使用者输入
(setq baspt (getpoint “请求输入基准点:”))
(setq rad (getdist baspt “\n请求输入小圆半径:”))
(setq num (getint “\n请求输入欲相切的小圆数量:”))
;只要能求得 cenpt 点,再以 array 指令配合就万事OK了
;以下ang1、kk、cenpt值须由程序依据baspt、rad、num求出
(setq ang1 (/ (* pi 2) (* num 2)))
(setq kk (/ rad (sin ang1)))
(setq ang2 (- (/ pi 2) ang1))
(setq cenpt (polar baspt ang2 kk))
;以下依据 cenpt、num 配合环形array画出多圆相切
(command “circle” baspt rad) ;;先画一个圆,才能array
(command “array” (entlast) “” “p” cenpt num 360 “Y”)
(prin1)
)
(prompt “\n << 5TEST2>>自动等圆相切绘制”)
(prin1)
步骤四:执行程序 5test2.lsp
指令:(load "5test2") <-- 加载程序
<< 5TEST2>> 自动等圆相切绘制 <-- 传回之讯息
指令:5test2
请求输入基准点: <-- 请给小圆基准点
请求输入小圆半径: <-- 请给一实数 30
请求输入欲相切的小圆数量: <-- 请给一整数 8 个
执行结果:
步骤五:程序改良&注意重点
重点1. (setq ang1 (/ (* pi 2) (* num 2)))亦可直接写为 (setq ang1 (/ pi num))
重点2. (setq kk (/ rad (sin ang1))) 来由推算方式如下
因为 Sin(ang1) = 对边 / 斜边 = rad / kk
所以 kk = rad / Sin(ang1)
改成LISP表示式->(setq kk (/ rad (sin ang1)))
重点3. 因为 ang1 + ang2 = pi / 2 来由推算
所以 (setq ang2 (- (/ pi 2) ang1))
或 (setq ang2 (- (* pi 0.5) ang1))
重点4. 因为rad的取得,乃以getdist方式所以在问半径时,亦可由屏幕中给一段距离当半径
重点5. Array 指令后的七个运算子自变量必须配合正常执行之顺序给与,是相当严谨而不是乱凑的!!!
指令: ARRAY
选取对象: (entlast) 找到 1 个 <-前一个动作,刚画的小圆
选取对象: <-[Enter] 结束选取
矩形数组(R)/环形数组(P) <P>: P <-环形数组选项
基准(B)/<指定数组的中心点>:<-给数组的中心基准点
5.项目个数: <-给一整数
6.要布满的角度 (+=逆时钟, -=顺时钟) <360>:
<-内定360度
7.复制时旋转对象? <Y> <-是否旋转,内定Yes
所以才有以 command 函数呼叫 AutoCAD 指令产生
(command "array" (entlast) "" "p" cenpt num 360 "Y")
或改写成
(command "array" "L" "" "p" cenpt num "" "")
· 指令一定要加双引号,如 "array"
· 复选项一定要加双引号,如 "L" 、"P"、"Y"
· 用内定值,务必要加上连续二个双引号,如 ""
· (entlast) 是AutoLISP标准函数,可抓取图面中最后完成的体元是很好用的技巧,请多加注意
七、本章结语:
以AutoLISP作参数设计是相当重要的入门课题,让原本辛辛苦苦画半天的图,经由您的AutoLISP妙手,短短几十行LISP程序,竟在瞬间完成,那种喜悦与成就感相当令人感动的,当然对提升设计及绘图效率更是显而卓著的至于离记忆中很久久以前的三角函数,您当然得再重新呼唤回来,相信经过本章的诀窍分析,您将不再害怕面对三角函数了,甚至将因三角函数在您程序中的发威,而使您开始喜欢三角函数了,果真如此,相信尔后其它再多再复杂的参数设计图形也难不倒您了,笔者在此先恭喜您参数设计若要有专业的水准,务必要配合DCL交谈框设计,有一个漂亮且容易输入各种资料的交谈界面,此部份请参考【AutoLISP& DCL精华宝典下册】中有详细的技巧解说希望您在进入下一章之前,务必务必把第六单元的二题举一反三作完确定完全没问题后再向下一关挑战,否则基础没打稳,眼高手低,或光看不练,那到时您的AutoLISP功力一定是花拳绣腿,不堪一击!!!
|
|