学习lisp二次开发,我们从几个简单图形开始!
我们论坛不知是因为学的人少,还是怕别人把自己的本事学到,关于CAD二次开发的帖子特别少。小弟我在11月10发表求助帖《关于角度替代》(http://www.askcad.com/bbs/thread-15530-1-1.html)没有得到满意答案后,开始自己尝试学习二次开发。一开始我学VBA,前几天转学LISP,感觉LISP要比VBA好学多了,当然,这是我个人看法。其实这方面我学到的还是很少,我之所以发这个小小教程,是希望抛砖引玉,一引的是想学而又不知道如何下手的菜鸟朋友,让更多的人参与学习中来;二引的是藏卧在本论坛的高手们,要是他们肯出来相教,那吾等菜鸟就有福了。:lol
言归正传,下面我们从几个简单的例子开始,先学画一条直线,这是CAD最基本的了,在LISP里又该如何写呢?下面请大家依瓢画葫芦把下面代码加入到CAD里。
一:在D盘根目录下新建一个记事本文档,改名为:line.lsp,lsp是文件的后缀名,替换了原来的txt,注意,如果你的文件的后缀没有显示出来,那就一定要让它显示出来才能改,方法是:工具》文件夹选项》显示》高级设置里》把“隐藏已知文件类型的扩展名”前面的钩去掉,这本是题外话,但考虑可能还有朋友不会改,顺便也就提一下。
二:打开line.lsp,把下面代码复制到里面去,保存。
(defun c:zx()
(setq p1 (getpoint "起点:"))
(setq p2 (getpoint "端点:"))
(command "line" p1 p2 ""))
恭喜你!你已经成功的制作出了第一个LISP程序。
三:打开autoCAD,工具》加裁应用程序,选中我们刚才保存的line.lsp,按加裁,关闭。或者直接在命令行里输入:(load "d:/line.lsp"),回车,注意括号和双引号都不能少,而且必须是在英文状态下输入的。
四:在命令行输入zx,回车,就像我们平时在命令行输入命令一样。根据提示在命令行里输入坐标值,或者直接在屏幕上分别截取起点和端点。
再次恭喜你第一次将自己制作的LISP程序成功的在CAD里绘制出了图形!
细心的朋友可能会发现直线是画出来了,但绘制过程中有些东西并不太理想,是不是?那当然了,这是最简单的代码嘛,在将后的下一节我将对代码一一进行解释,并完善它的部分缺陷。
在下也是初学者,免不了会出错,请大家不要见笑,但如果你要帮我指正出来,那我太欢迎了!:lol
后面内容在6楼、12楼
(建议大家到小朱版主在2006-12-28 发表的贴子里下载《AutoLIST&DCL基础篇》这本教程,我觉得这本书非常不错,很易懂。http://www.askcad.com/bbs/viewthread.php?tid=6279&extra=page%3D1%26amp%3Bfilter%3Dtype%26amp%3Btypeid%3D4
没有pdf阅读器可以找我)
[ 本帖最后由 leimc 于 2007-12-13 20:48 编辑 ] 有机会得好好学习一下!! 我也想学,就是语法和函数不知道:Q
[ 本帖最后由 xuehong51 于 2007-12-13 17:09 编辑 ] 有个问题想问一下,lisp二次开发有什么好处呢?难道现有的CAD命令不够完善吗?:P
回复 #4 kewang 的帖子
:) CAD的命令很强大,但不能说很完善,要不为什么出了20004还要出2005,出了2005还要出2006不断的升级呢?我们每个人对CAD的功能需求都不尽相同,CAD也不可能兼顾到我们每个人的需求,要不然CAD软件那得要多大才行。本贴刚开始我就提到我发过一个叫《关于角度替代》的求助贴,autoCAD的角度替代我觉得不好用,那它对我而言就是一种缺陷,这时候我们可以用LISP创造出一个更符合自己要求的新命令来,大大简化原本繁琐的环境设置或操作步骤,这就是LISP的好处。 第二节(defun c:zx()
(setq p1 (getpoint "起点:"))
(setq p2 (getpoint "端点:"))
(command "line" p1 p2 ""))
下面我来解释一下
(defun c:zx()
;这是程序的开头部分,以defun功能函数定义新的命令或新的功能函数,在上面例子中,我们就是以zx为新命令在CAD里使用的,这个新命令可以根据你自己的喜好设置,但是不能与原有的命令相同,要不然它会把原有的命令覆盖掉。
(setq p1 (getpoint "起点:"))
;用setq功能函数为变量p1 p2设定变量值,格式为(setq 变量名 变量值)
这里的变量值由我们自己输入,getpoint为等待输入函数,格式为(getpoint "提示内容"),提示内容用来提示使用者下一步如何操作,可以省略,get意为获得,point是点的意思,加起来就是获得点
我们可以在命令行输入一个坐标值,也可以在屏幕上直接用鼠标获取,这里整句的意思就是获取一个坐标,把它的值赋给变量p1。
(setq p2 (getpoint "端点:"))
;获得第二个点
(command "line" p1 p2 ""))
;有两个点我们就可以绘制一条直线了
command中文意思为命令,line为CAD里的直线命令,这里用command把它从CAD里调用出来,LISP最讨人喜欢的特点就是它能直接调用CAD命令,这比VBA方便多了
后面跟的是这条直线的起点p1、端点p2,因为变量p1、p2在前面已经被赋值了的,它们代表的就是两个点坐标
再后面两个双引号不能少,表示什么都不选,用来结束选择,要不然它会一直提示输入下一点,line两边的双引号也不能少,这里把line当成是一个字符串,所有双引号里面的内容均为字符串数据类型,关于数据类型我们以后再讲,括号也不能少,它总是成双成对的,一个函数一对括号,代表的是一个范围。
在下自古以来表达能力都比较差,也不知道大家能不能看懂。
现在布置一个练习
获取三个点坐标,绘制一个三角形
我将在下一节开始处将代码写出来,看看你写的和我写的是否相同。
[ 本帖最后由 leimc 于 2007-12-13 16:15 编辑 ] 这样对吗
(defun d:\cadlisp\sjx()
(setq p1 (getpoint "第一点:"))
(setq p2 (getpoint "第二点:"))
(setq p3 (getpoint "第三点:"))
(command "line" p1 p2 p3 p1 ""))
对的,试了:D
[ 本帖最后由 xuehong51 于 2007-12-13 09:05 编辑 ] defun d:\cadlosp\sjx()(askcad.com)
(setq p1 (getpoint "第一点:"))
/www.askcad.com(setq p2 (getpoint "第二点:"))
1a/b!o8M3k6nCAD设计论坛(setq p3 (getpoint "第三点:"))
(command "spline" p1 p2 p3 p1 "")) 没有最外面的一对括号,加载以后直接运行,加上括号又不行了,加载以后不能用,不知为什么:(
[ 本帖最后由 xuehong51 于 2007-12-13 09:23 编辑 ] ;P defun后面的是新建命令名,不是路径,为c:新命令名。 哈哈,闹笑话了:$ 这回行了。我说不懂语法不行吗:D
第三节
按照我们前面的思路,代码就应该是:(defun c:zx()
(setq p1 (getpoint "第一点:"))
(setq p2 (getpoint "第二点:"))
(setq p3 (getpoint "第三点:"))
(command "line" p1 p2)
(command "line" p2 p3)
(command "line" p3 p1))
因为画直线时它会一直提示输入下一点,所以我们也可以将三个command函数合并成一个,也就是
(command "line" p1 p2 p3 "c")
c是闭合,不选的话它就只能画出p1p2、p2p3两条直线。
这是用三条直线绘制一个三角形,我们也可以用多段线来绘制,多段线的命令为:pline
(command "pline" p1 p2 p3 "c")
修改后就是:
(defun c:zx()
(setq p1 (getpoint "第一点:"))
(setq p2 (getpoint "第二点:"))
(setq p3 (getpoint "第三点:"))
(command "line" p1 p2 p3 "c"))
或者
(defun c:zx()
(setq p1 (getpoint "第一点:"))
(setq p2 (getpoint "第二点:"))
(setq p3 (getpoint "第三点:"))
(command "pline" p1 p2 p3 "c"))
用同样的方法我们还可以绘制出4边形、5边形、六边形……
在绘制过程中有些东西不太理想,现在我们修改并改进一下
第一,输入命令zx后,第一点:第二点:第三点:紧跟在后面显示,不会换行
解决办法:在提示字符串前加\n,表示换行,即:
(setq p1 (getpoint "\n第一点:"))
(setq p2 (getpoint "\n第二点:"))
(setq p3 (getpoint "\n第三点:"))
二,图形画完后,line命令操作过程也跟着显示出来,不但影响速度,也没有实际意义
解决办法:在程序开始部分加入下面一行
(getvar "cmdecho" 0)
设置系统变量cmdecho=0关闭命令响应。getvar是设置系统变量的函数,它可以把CAD里的系统变量调出来修改。
三,全部过程执行完后,命令行出现空响应nil
解决办法:在程序结束前加入下面一行
(prin1)
注意:是prin1,最后一个字符是123的1,不是字母L的小写
四,为了不占据内存,我们可以把所有变量均处理成局部变量
解决方法:
把全部变量放在新命令后的括号里的右斜杠的后面,既
(defun c:zx(/ p1 p2 p3)
五,我想在程序加裁时显示我的名字,让使用者知道这个程序是我创作的,或者其它对使用者操作进行提
示的内容
解决办法:在程序结束后加入prompt函数,
(prompt "本程序作者:张三")
经改进,代码为:
(defun c:三角形(/ p1 p2 p3)
;命令也可以是中文
(setvar "cmdecho" 0)
(setq p1 (getpoint "\n第一点:"))
(setq p2 (getpoint "\n第二点:"))
(setq p3 (getpoint "\n第三点:"))
(command "pline" p1 p2 p3 "c")
(prin1))
(prompt "\n本程序作者:张三\n欢迎你使用本程序")
(prompt "\n我能自己创作程序了,我很高兴!")
[ 本帖最后由 leimc 于 2007-12-13 16:29 编辑 ] 测试成功:victory: prompt的文字内容仅在加载后显示一次。 创作无限~~~~~~~支持~~~~~~~
回复 #13 xuehong51 的帖子
放在程序外面它就只在加裁的时候显示,如果把它插入程序里面,那程序每次运行到这里都会显示,比如下面我把(prompt "\n本程序作者:张三\n欢迎你使用本程序")移动到"第一点"和第二点之间 ,(defun c:三角形()
;命令也可以是中文
(setvar "cmdecho" 0)
(setq p1 (getpoint "\n第一点:"))
(prompt "\n本程序作者:xuehong51 \n欢迎你使用本程序")
(setq p2 (getpoint "\n第二点:"))
(setq p3 (getpoint "\n第三点:"))
(command "pline" p1 p2 p3 "c")
(prin1))
(prompt "\n我能自己创作程序了,我很高兴!")
那程序每运行完第一点:都会显示
本程序作者:xuehong51
欢迎你使用本程序
然后才显示第二点:
这主要是看你把prompt放在哪里。
[ 本帖最后由 leimc 于 2007-12-13 20:24 编辑 ]