LISP 编程教材.docx
- 文档编号:11078494
- 上传时间:2023-02-24
- 格式:DOCX
- 页数:56
- 大小:44.65KB
LISP 编程教材.docx
《LISP 编程教材.docx》由会员分享,可在线阅读,更多相关《LISP 编程教材.docx(56页珍藏版)》请在冰豆网上搜索。
LISP编程教材
AutoCAD在测绘图形处理中的应用
近年来,测绘领域内机助制图的研究取得了飞速发展,通过绘图机输出的图形从过去简单的工程制图到现在的各种比例尺的地形图、地藉图、宗地图,以及非常复杂的小比例尺土地利用现状图等。
在众多的绘图系统中,人们普遍采用的基础绘图软件是美国Autodesk公司的AutoCAD,因为该软件不仅具有丰富的绘图命令,还具有强大的图形编辑功能,而且软件运行相当稳定。
但是熟悉AutoCAD的人都知道,要用好AutoCAD,不但要熟练掌握其各项命令,而且要熟练掌握AutoCAD提供的数据交换文件SCR、DXF和嵌入AutoCAD内部的高级语言--AutoLISP语言,这样使您对各种图形,尤其对复杂的图形更加得心应手。
关于AutoCAD在测绘图形中应用可归纳为以下几个方面。
1实现数据到图形的自动转换
有了原始数据,如何实现自动成图,这一直是人门关心的问题,在AutoCAD下,把原始数据变成图形,可以通过以下途径:
(1)采用高级语言(BASIC语言或C语言)编制程序调用原始数据文件生成SCR命令文件,在AutoCAD的图形编辑环境下调用SCRIPT命令执行该文件,生成相应的图形。
(2)用高级语言生成DXF文件,在AutoCAD图形编辑环境下调用DXFIN命令打开该文件,即可得到相应的图形文件。
(3)用高级语言直接生成DWG图形文件
(4)利用AutoLISP语言,编写相应程序,读取有关数据文件,进行处理,并且调用AutoCAD绘图命令,直接生成图形。
以上四种方法中,第一种方法比较简单,但执行速度慢;第二种方法速度较快,但DXF文件格式死板,记录冗长,尤其是复杂的图形,DXF文件长得惊人。
第三种方法较前两种方法理想,但这种方法对于一些复杂的图形尚有一定的难度,况且,不同的AutoCAD版本,DWG文件的结构也不同,使程序不能通用。
三种方法都有一共同的特点,先在AutoCAD外,用高级语言做数据处理,然后再回到AutoCAD下成图,效率低。
第四种方法是直接在AutoCAD下工作,减少了中间环节,提高了效率。
而且具有较强的通用性,对一些较复杂的图形,更直接方便。
2实现图形到数据的自动转换
刚接触AutoCAD的人都有下面的感觉,就是由数据生成图形容易,由图形返回数据困难,有LISP语言,这个问题就会迎刃而解。
2.1图纸资料的数字化
要把图像资料变成相应的数据,一般是通过数字化仪和扫描仪。
对于手扶式数字化仪来讲,我们可以根据不同要求来编制相应的LISP程序,完成图形的数字化。
程序运行时,把从数字化仪传递来的数据信息(点的坐标)连同交互式状态下输入的有关编码合并以一合理的数据结构存贮于数据文件中,同时,在屏幕上,采用不同的图层,不同的颜色进行同步显示。
从而使数字化过程变得非常直观、形象,避免产生丢点或重复等各种错误的发生。
这样数字化的结果,不仅得到与原图纸相对应的数据文件,也同时生成了一幅相对应的图形文件。
数据文件可以纳入有关相对应的数据管理系统中,而图形文件为将来的输出和变更修改提供了方便。
对于扫描仪,是将原图通过扫描仪扫描形成位图文件(文件扩展名为BMP或TIF),经矢量化软件把图形的数据信息分类存贮于数据文件中。
2.2图形变更后,数据的自动更新
测量领域的各种图形随时间的推移是不断发生变化的,为保证图形的现实性,就要对图形随时加以修改,这种修改大多数是直接对原图文件利用AutoCAD的图形编辑功能来完成,但随之产生一个问题,就是图形文件修改后,原图对应的数据文件如何修改?
解决这个问题的最好办法是利用AutoLISP语言。
在AutoLISP语言中,有很多实体访问函数,实体名称函数、实体数据函数,运用上述函数编制一个LISP程序就可以实现图形文件到数据文件的自动转换。
具体过程如下:
用ssget函数构造一个选择集,在利用sslength函数求出选择集实体的个数,然后ssname函数依次求出每个实体的名称,在通过entget函数就可以获得实体的下列信息:
实体类型,所在层名和实体颜色号(一般图形的编码就隐含在图层和颜色中)。
实体类型常见有:
组合线、直线、注记和块。
如果实体是直线,我们就可以直接读取直线的起始坐标。
如果实体是注记类,我们可以读取注记内容,字符高度,方向及注记点位坐标。
如果实体是块,我们就可以直接读取块名,插入点位,旋转角度和X、Y方向比例因子。
如果是组合线,可利用entnext函数依次读取线上的各点坐标。
把上面获得数据按所需要的格式,输入到相应的数据文件中,即实现了图形到数据的自动转换。
这样一来,如果原图形中某一范围需要修改的话,就可以利用AutoCAD编辑命令完成,甚至可以把原图中元素删除掉,重新绘制,修改完成后,运行上述LISP程序,给出变更范围,计算机立即生成一个新的数据文件,重新纳入管理系统中去,从而保证了图形于数据的统一。
2.3利用图形和数据相互转换功能进行控制网的优化设计
控制网的精度取决于网形结构和观测量的精度,控制网的结构主要任务是确定合理的网形结构。
这个过程完全可以在AutoCAD下完成。
首先,把已知数据输入计算机,初步确定待定点的位置,再用边长和方向把这些点连接起来构成控制网。
网中已知点、未知点及观测边、观测方向均用不同的图层和颜色加以区分。
然后,把该网形转换成相应的数据文件,则该数据文件含有网形的所有点位及观测信息。
调用相应的精度估算程序,对该网做精度分析,其结果仍以图形形式返回AutoCAD中,如各点的误差椭圆等。
设计者将根据这些精度指标,参照设计要求,合理调整该网的结构,反复上述过程,最后,完成该控制网的优化设计,输出该网设计图和精度分析结果。
3用LISP程序实现图形的批量编辑
在测量图形处理中,经常会遇到需要批量处理某类图素的情况。
如地形图中的一些专用符号及注记字符的大小需要统一放大或缩小;图中的植被符号需要统一调整密度等。
如果我们采用手工逐一编辑的话,工作量相当大,效率很低,尽管这类问题编辑工作量大,但规律性极强,我们可以编制一段相应的LISP程序来自动完成。
具体作法是,首先是在AutoCAD下构造一选择集,集内包含所有需要修改的实体,然后逐一求出各个实体的名称,并对该实体有关数据做相应的修改。
类似的批量编辑问题还很多,如修改某一类实体的图层或颜色,删除满足一定条件的所有实体等等。
均可以通过LISP程序来完成,从而大大地提高编辑的工作效率。
4用LIST语言开发新的功能函数
AutoCAD已经为我们提供了丰富的绘图和编辑命令,但是这些命令并不是针对测量专业而设置的。
有些测量方面常用的功能AutoCAD并不具备,但可以利用LISP语言对AutoCAD作二次开发,开发出适应测量专业特点的新命令。
这里只举几个简单的例子加以说明:
在地形测量中,
(1)如果我们测量了某一矩形建筑物的四个点,则很容易把这个建筑物绘制出来。
但大多数情况是,我们只测量了这个建筑物的一条边,丈量了建筑物的宽度,这种情况,显然AutoCAD提供的LINE或PLINE命令是无法实现的。
(2)在地形测量中,加固陡坎、末加固陡坎、铁路、电力线路,围墙,界址线等等地貌符号和图式符号的绘制,AutoCAD没有提供相应的绘图命令,为此,我们都可以编制相应的LISP程序来自动处理完成。
以在编辑土地利用现状图时,经常需要知道某一宗地的面积,同样也可以编制一个LISP程序,它的功能是把围绕宗地四周的线提出来,首尾相接,构成封闭的多边形,计算其面积并显示出来。
类似的,我们可以编制若干个LISP程序,每一个程序完成一个相应的功能,把这些程序嵌入AutoCAD内部,调用AutoCAD时一同装入内存,我们就可以象调用其它AutoCAD命令一样,随意调用,方便、灵活地完成各种编辑工作。
5图形坐标还原、方位旋转及换带处理
在地形图或地籍图测量中,会遇到这样的情况,图形已经测绘完毕,但坐标系统用错或需要换带处理,或需要把图形扭转(还原)或处理到需要的坐标系统。
AutoCAD可以帮助您完成上述工作。
具体的办法是:
对于坐标系统用错,在测图区域内找相距较远的两个已知点,计算确定对的和错的两组坐标,分别计算两点之间边的方位,确定出需要扭转的角度。
如果是数字化地形图或地藉图,直接在AutoCAD环境下调出所有图幅,关闭纯地形图或地籍图以外的图层(如图廓等图层)。
利用MOVE命令移动整块图形,移动基点选取上述已知点中错误的一个。
再利用ROTATE命令旋转整块图形,旋转基点选择已知点中正确的一个。
经移动和旋转正确后的图形由WBOLCK命令存盘,重新调出该图形,再重新分幅和加图廓等信息。
换带处理,方法类似。
如果不是数字化的图形,需要将该图形通过数字化仪或扫描仪加上相应的软件处理成AutoCAD下的图形,按上述方法,即可完成图形坐标还原、方位旋转及换带处理。
6GPS点、导线点、图根点展点在分幅图上
大比例尺、大面积的地形图或地籍图测量,规范要求除必需的导线点外,还需要大量的图根点,少则几百个,多则几千个。
人工找点将其上在相应图幅上,工作量大,效率低,还容易错。
计算机加AutoCAD就容易多了。
具体方法是这样,先将各点的点号、坐标按规定的格式录入计算机形成数据文件,检查无错误后,通过展点程序调用该数据文件,生成与AutoCAD连接的交换文件(扩展名为SCR),然后在AutoCAD下用SCRIPT命令执行该交换文件,即可得到已上好点的总体分幅图。
这样哪一个点在哪一幅图上,一目了然,通过打印机或绘图机输出该图。
AutoCAD还有许多功能可供我们测绘行业运用,有待我们去挖掘,也望同仁相互交流,共同发展,为测绘事业作出贡献。
AUTOCAD中的几个LISP程序
机械制图中,常常得做许多大量的重复工作。
下面这几个用Lisp编写得程序,是我画图时经常使用的,节省了我的不少时间,希望也能帮助广大使用AUTOCAD的工程师们。
1.自动求和
机械制图中材料表的填写是毕不可少的,填写完后还需根据材料表求出总重量。
一般一幅图中常有几十个物体,将这些重量一项一项相加个繁琐的过程,而且容易出错。
使用下面这个程序,只需用鼠标选定需要相加的数,其和就会自动的显示在命令行中。
因为在AUTOCAD中没有“数”这种实体,所有的数都以实体“TEXT”存在,所以程序中使用了“atof”函数,将以字符串形式表示的数转换为实数。
(defunc:
total(/cmdmodessetsslnssettempssl1total)
(if*error*quit)
(setqcmdmode(getvar"cmdecho"))
(setvar"cmdecho"0)
(prompt"\nSelectnumberstoadd:
")
(setqsset(ssget))
(if(nullsset)
(princ"\nError:
Nothingselected!
\n")
;过滤出选中的“text”实体,并报告有多少“text”实体被选中。
(progn
(setqssl(sslengthsset))
(setqnsset(ssadd))
(while(>ssl0)
(setqtemp(ssnamesset(setqssl(1-ssl))))
(if(=(cdr(assoc0(entgettemp)))"TEXT")
(ssaddtempnsset)
)
)
(setqssl(sslengthnsset))
(printssl)
(princ"textentitiesarefound.")
;选出所有可转化为数的“TEXT”,并求和。
(setqtotal0)
(setqssl1ssl)
(while(>ssl0)
(setqtemp(ssnamensset(setqssl(1-ssl))))
(setqnumber(atof(cdr(assoc1(entgettemp)))))
(if(=0number)
(setqssl1(1-ssl1))
(setqtotal(+totalnumber))
)
)
;显示和及加数的个数,便于用户检查是否多选或漏选。
(princ"\nThetotalis")
(princtotal)
(princ"ofthe")
(princssl1)
(princ"numbers\n")
)
)
(setvar"CMDECHO"cmdmode)
)
(princ"\n\tc:
totalloaded.Startcommandwithtotal.")
2.自动生成递增数
用CAD作图时,常需画一些距离一定、数值递增的数。
如填写材料表时,“序号”一栏就需填写由下至上的递增数。
通常,我们先用“text”命令写一个数,再用“array”命令将其按一定方向阵列,最后用“edit”命令一个一个的改正。
下面这个程序可将你从这单调重复的动作中解放出来。
(defunc:
arn(/enttempdanumberyorn)
(setqcmdmode(getvar"cmdecho"))
(setvar"cmdecho"0)
;选择一个实体,并判断能否作为生成递增数的初始数。
(setqent(entsel"\nSelectnumbertoarn:
"))
(if(nullent)
(progn
(princ"\nError:
Nothingselected!
\n")
(exit)
)
)
(setqtemp(entget(carent)))
(if(=(cdr(assoc0temp))"TEXT")
;输入生成递增数的个数、数间距及其方向。
(progn
(setqnumber(getint"Numberoftexts:
"))
(setqd(getdist"Distbetweentexts:
"))
(setqa(atoi(cdr(assoc1temp))))
(initget1"VH")
(setqyorn(getkword"Direction(V/H)?
"))
(if(=yorn"V")
(setqp(list0d))
)
(if(=yorn"H")
(setqp(listd0))
)
;重复拷贝前一个数,并将拷贝数加1。
(while(/=number1)
(command"copy"ent""p"")
(setqent(entlast))
(setqtemp(entgetent))
(setqa(+a1))
(entmod(subst(cons1(itoaa))
(assoc1temp)temp))
(setqnumber(1-number))
)
)
)
(setvar"CMDECHO"cmdmode)
)
(princ"\n\tc:
arnloaded.Startcommandwitharn.")
3.修改编号
作图时,常常需要对图中的物体进行编号,有时会在已编好号的物体中插入几个物体,那么在这之后的编号都需作相应的增加。
对于比较多的编号,一个个的寻找再修改就很麻烦,下面这个程序可以自动完成对编号的寻找及修改过程。
为了能够清楚的看清要改变的数字及及其所处的位置,用变量“h”记录数字的高度,变量“viewctr”及“viewsize”记录了使用命令前的视窗中心及其大小。
(defunc:
chn(/cmdmodeviewctrviewsizessetijksslnssettempentnumberx1y1xyhyorn)
(defun*error*(s)
(exit)
)
(setqcmdmode(getvar"cmdecho"))
(setvar"cmdecho"0)
(setqviewctr(getvar"viewctr"))
(setqviewsize(getvar"viewsize"))
(prompt"\nSelectnumberstoadd:
")
(setqsset(ssget))
(if(nullsset)
(progn
(princ"\nError:
Nothingselected!
\n")
(exit)
)
)
;根据用户指定范围过滤出需要改变的编号,并报告找到多少编号。
(setqi(getint"\nThenumberfromwhichtochange:
"))
(setqj(getint"\nThenumbertowhichtoadd:
"))
(setqk(getint"\nHowmuchyouwanttoadd:
"))
(setqssl(sslengthsset))
(setqnsset(ssadd))
(while(>ssl0)
(setqtemp(ssnamesset(setqssl(1-ssl))))
(if(=(cdr(assoc0(entgettemp)))"TEXT")
(progn
(setqnumber(atoi(cdr(assoc1(entgettemp)))))
(if(and(<=inumber)(>=jnumber))(ssaddtempnsset))
)
)
)
(setqssl(sslengthnsset))
(if(=ssl0)(prognprinc("\nNonumbersselected!
")(exit)))
(printssl)
(princ"numbersarefound.")
;使被改变编号以一定大小处于屏幕中心位置并被高亮度显示,
;改变每个编号前先询问用户,以免改变了不想改变的编号。
(setqx1(carviewctr))
(setqy1(cadrviewctr))
(setqent(entget(ssnamensset(-ssl1))))
(setqh(cdr(assoc40ent)))
(while(>ssl0)
(setqent(entget(ssnamensset(setqssl(1-ssl)))))
(setqx(cadr(assoc10ent)))
(setqy(caddr(assoc10ent)))
(if(or(>(abs(-xx1))(*h10))
(>(abs(-yy1))(*h6)))
(progn
(command"zoom""c"
(listxy)
(*h20)
)
(setqx1x)(setqy1y)
)
)
(redraw(cdr(assoc-1ent))3)
(initget1"YesNo")
(setqnumber(atoi(cdr(assoc1ent))))
(princ"\nThenumber")
(princnumber)
(setqyorn(getkword"tobeChanged?
(y/n)"))
(if(=yorn"Yes")
(entmod(subst(cons1(itoa(+numberk)))
(assoc1ent)ent))
)
(redraw(cdr(assoc-1ent))1)
)
;所有编号改变完成后,恢复使用本命令前的视窗。
(command"zoom""c"viewctrviewsize)
(setvar"CMDECHO"cmdmode)
)
(princ"\n\tc:
chnumberloaded.Startcommandwithchn.")
4.自动画管线图的小程序
画一些管路原理图时,常常有许多管路在图中相交,而这些管路实际并不相连。
我们常把在相交点处次要的管路断开,在用一半圆连接两断点,下面的程序可以帮助大家完成做这一繁琐的工作。
程序中使用“break”命令截断需要被断开的管线,再用“arc”命令画一半圆连接两断点。
变量p读取管线交点;p1、p2为点p的左右或上下两点;p3为连接p1、p2半圆的中点。
由于使用“break”命令时若AUTOCAD环境处于对象捕捉方式(OSMODE≠0),则“break”命令截断的p1、p2两点可能为变为p1、p2附近的捕捉点。
所以程序开始时用变量myosmode记录系统变量OSMODE,而后设置OSMODE为0,程序结束后再设置还原OSMODE。
变量horn判断用户需要断开的是水平线还是垂直线。
(defunc:
brel(/myosmodehorvpp1p2p3)
(setqmyosmode(getvar"OSMODE"))
(setvar"OSMODE"0)
(setqp(getpoint"\nSelectpointtobreak:
"))
(initget1"HV")
(setqhorv(getkword"Direction[H/V]?
"))
(if(=horv"H")
(progn
(setqp1(list(-(carp)1.5)(cadrp)))
(setqp2(list(+(carp)1.5)(cadrp)))
(setqp3(list(carp)(+(cadrp)1.5)))
)
(progn
(setqp1(list(carp)(-(cadrp)1.5)))
(setqp2(list(carp)(+(cadrp)1.5)))
(setqp3(list(+(carp)1.5)(cadrp)))
)
)
(command"break"p1p2)
(command"arc"p1p3p2)
(setvar"OSMODE"myosmode)
(princ)
)
(princ"\nStartcommandwithbrelwhichwillbreakalineandjoinitwithanarc.")
1.设定环境变量
setMS_RTCONFIG=TradChinese(本行可以加入autoexec.bat)
2.建立一个批次档test.bat
msbatchdwgoutinput:
c:
\dgn\*.dgnoutdwg:
c:
\dwg\
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LISP 编程教材 编程 教材