【摘要】本文介绍了用户幻灯菜单及功能和开发方法,并给出了标高标注和图例绘制程序的开发方法以及程序注解。
1用户幻灯菜单简介用户幻灯菜单(下文简称幻灯菜单)是在AutoCAD平台上开发的一种高效实用的用户图形界面,由幻灯和相应的AutoLISP实用程序组成。其功能及用法类似于AutoCAD的图标菜单。调用时幻灯菜单屏幕上出现一幅幻灯,幻灯显示不同图形界面,由幻灯和相应的AutoCAD实用程序组成。其功能及用法的功能区域,每个区域对应相应的功能,用鼠标点取即可调用该功能。
幻灯菜单可以用于开发本部门使用的工具软件或是商业化的CAD软件,可以大大提高开发效率以及设计绘图速度。
下面以我院开发的标高标注程序为例介绍幻灯菜单的功能:在command:状态下从下拉菜单中点取“标高标注1”后屏幕上出现如图1所示幻灯,用鼠标在某一标高种类格中点击后幻灯消失,恢复前一图面,在提示行中提示“请输入起点”,给点后又提示:“标高值”,输入数值后自动按选择的种类画好标高符号并写好标高值;然后重复提示“请输入起点”标注下一个,回车则回到图1幻灯重复使用,点EXIT退出。
2幻灯菜单的特点
幻灯菜单可以实现AutoCAD的图标菜单的各项功能,并且有如下优点:
a.制作、修改效率高。制作图标菜单时,要实现的功能数与幻灯数及菜单项的数量相同。而制作一个幻灯菜单只需要作一个幻灯,幻灯数量大幅减少,修改也容易得多。
b.使用效率高。为了提高软件效率,尽量减少击键次数是今后软件的发展方向。幻灯菜单可以将多种形式的选择以图形形式直观地显示出来,以供选择。以标高标注为例,以前的方法是先问标高符号形式,再问方向,而使用幻灯菜单只需点取一次即可。
c.界面美观,制作灵活多样,使用方便。幻灯菜单在一幅幻灯中划分的功能区数量不限,并且可以根据需要制作成方格、横格、竖格、扇型格、圆环格等多种形式,甚至可以达到可编程序对话框的很多功能。
d.适用性强,移植方便。幻灯菜单适用于R9.0版以上的各种中、西文AutoCAD版本。使用幻灯菜单时,由于它包含在用ADS或AutoLISP等语言编制的程序中,所以只要能运行程序即可调出幻灯菜单,版本升级时不必改变新的菜单文件。而图标菜单的菜单项必须逐条加入到新的菜单文件中。
e.可以作成定型模块重复使用,从而大大提高编程效率。
3幻灯菜单的制作
幻灯菜单的原理是:将AutoCAD绘图区分为若干规则的图形区域,每一区域可以对应一组功能,在程序调用幻灯菜单时,要求用户根据需要在某一图形区域中选取一点,然后程序自动计算出该点所在的区域位置,从而调用所对应的程序功能。
点的定位是幻灯菜单制作编程的关键所在,以矩形格幻灯菜单为例,其步骤是:
a.获取下列AutoCAD系统变量:
viewsize-当前绘图区高,用绘图单位计算;
viewctr-当前绘图区中心点坐标值;
vsmax、vsmin-虚拟屏幕的左下角及右上角点坐标值,可以用来求绘图区宽高比,从而求出绘图区宽度。
b.根据横向和竖向分格数,求出每格的宽和高。
c.由点的坐标值分别求出点所在格的横向和竖向序号。
d.横向和竖向序号连接即可获得该格的区域代码。
后文将给出我院开发的标高标注和图例绘制两个实例,以下程序均在AutoCADR10至13各版本下顺利运行,并已非常成熟。需要指出的是,为了简化程序,突出重点,删去了一些诸如容错或装饰性的语句,但不影响程序运行。
4实例一———标高标注程序
由程序abg.lsp和幻灯文件acdl.sld文件组成,使用说明已在前面叙述,标题7a给出abg.lsp程序清单及注解
abg.lsp程序包括主程序abg和15个标高标注子函数,子函数abgl至abg15类似,本文只列出abgl子函数程序。
5实例二———图例绘制软件本软件由用户在6页幻灯菜单中连续选取图例,给出一个插入图例的左上角点后,程序自动将所选择的图例按顺序逐项向下排列连续绘出。软件由Au toLISP程序atl.lsp和6页幻灯以及近百个图块组成。幻灯文件为atl1~atl6.sld。图块名为atlabc.dwg,atl为前缀,a代表幻灯页序号,为1~6;b代表幻灯菜单左右代码,左面为1,右面为2;c代表幻灯菜单中上下序号,分别为1~8。
本软件设计的核心思想是通过点的定位计算出的所对应的图例图块名,然后插入图例,多重选择由表处理语句来完成。本文中第7节的b部分给出atl.lsp中与幻灯菜单有关的程序清单及注解。后面还有几个子函数,由于篇幅有限本文不详细列出程序,只做简单介绍:
lastsld子函数对幻灯名字符串进行运算,求出上一页幻灯名;
nextsld子函数对幻灯名字符串进行运算,求出下一页幻灯名;
setnil子函数对各变量(必须包括whill)赋空值,并退出程序:
setok子函数对被选择的图例表进行处理,并逐项连续插入图例。
6小结
a.标高标注程序是利用幻灯菜单调出相应的标高标注子程序。
b.图例程序是利用幻灯菜单给图例名称赋值,然后运用字符串处理和表处理技术求得图例名称的列表,从而连续逐项插入被选中的图例。
c.图例幻灯菜单分两个大区,上面是图例区,下面是幻灯菜单的操作区,可见幻灯菜单能做成复杂高效的菜单。
7程序清单
a.abg.lsp程序及注解;
(defunC:BGBZ()
(setqwhil1t)
(whilewhil1)
(command″vslide″″acd1″)
(if(setqpp(getpoint″请点取标高种类″))
(progn
(redraw)
(setqh(getvar″viewsize″)
pcen(getvar″viewsize″)
pmax(getvar″vsmax″)
pmim(getvar″vsmin″)虚拟屏幕左下角)
(setqw(*(/(-(carpmax)(carpmin))
(-(cadrpmax)(cadrpmin)))h))
(setqpp0(list(-(carpcen)(/w3))
(-(cadrpcen(
/h3))))
(setqpp1(list(+(carpcen)(/w3))
(+(cadrpcen)(/h3))))
(setqdx(/w6)dy(/h6))
(setqlx(carpp)ly(cadrpp))
(setqplx(carpp0)ply(cadrpp0))
(setplx(-lxplx)ly(-lyply))
(setpx(fix(1+(/(-pxpx0)dx))))
(setqy(fix(1+(/(-pypy0)dy))))
(setqnn(strcat(itoax)(itoay)))
(cond((=nn14)(abg1))
((=nn13)(abg2))
((=nn12)(abg3))
((=nn11)(abg4))
主程序BGBZ开始
设whil1值为真
当whil1为真时执行下列程序
显示幻灯在幻灯菜单中选点
重画恢复原画面
绘图区高
绘图区中心点
虚拟屏幕右上角
共获取系统变量
求绘图区宽
有效区左下角,(有效区宽和高占绘图宽和高的三分之二)
有效区右上角
每格宽和高
PP点的X和Y坐标
左下角点坐标
PP点和PP0点X和Y坐标差;
X方向格序号
Y方向格序号
将X和Y连接
多项选择条件函数
nn=13时运行abe2子函数
((=nn24)(abg5))
((=nn23)(abg6))
((=nn22)(abg7))
((=nn21)(abg8))
((=nn34)(abg9))
((=nn33)(abg10))
((=nn32)(abg11))
((=nn31)(abg12))
((=nn44)(abg13))
((=nn43)(abg14))
((=nn42)(abg15))
((=nn41)(setqwhil1nil))
);cond)
)));progn;if;while;defun
(defunabg1()
(while(setqp1(getpoint″输入起点″))
(initget1)
(setqs1(getreal″标高值:″))
(setqp2(polarp108))
(setqp3(polarp2(/pi4)3.2))
(setqp4(list(+(carp2)0)(+(cadrp2)2.9)))
(if(=s10)(setps2″%%p0.00″)(setqs2(rtoss122)))
(command″line″p1″@14<0″″″″line″p3p2
″@3.2<135″″@12.8<0″″″
″text″p42.80s2)));……
b.atl.lsp程序及注解
为11-44格规定功能,即每一格对应一个子函数
主程序BGBZ结束
定义abg1子函数
标高符号起点
不接受空值
标高值
计算各点位置
标高为0时加“±”
画标高符号
写标高值command
while;defun-abg1a
bg2~abg15子函数省略
(defunC:TL()
(setqatllistniltlsld″atla″tlsldn″1″whil1t)
(setqtlpath″/cad/atl″)
(promtp″\n给排水图例程序
—BERIS″)
(whilewhil1
(command″vslide″(strcattlpath″atl″tlsldn))
(initget1)
(setqpp(getpoint″\n请连续点取图例,并点取〈确定〉″))
(setqh(getvar″viewsize″))
(setqpcen(getvar″viewctr″))
图例绘制主程序
赋初始值
图例图块路径
提示
当whil1为真执行下面程序调出幻灯(幻灯名由三个变量连接而成,图2为第一页)
不接受空值
以下内容同标高标注程序
(setqpmax(getvar″vsmax″))
(setqpmin(getvar″vsmin″))
(setqw(*(/(-(carpmax)(carpmin))
(-cadrpmax)(cadrpmin)))h))
(setqpp0(list(-(carpcen)(*w0.44))
(-(cadrpcen)(*h0.26))))
(setqpp1(list(+(carpcen)(*w0.44))
(+(cadrpcen)(*h0.44))))
(setqdx(/(*w0.88)4)dy(/(*h0.7)8))
(setqpx(carpp)py(cadrpp))
(setqpx0(carpp0)py0(cadrpp0))
(if(<pypy0)(dq2)(dq1))))
(defundq1()(if(<px(carpcen))
(setqaorb″1″)
(setqaorb″2″))
(setqxh(fix(1+(/(-pypy0)dy))))
(setqblkname
(strcat″atl″tlsldnaorb(itoaxh))))
(defundq2()
(setqxh1(fix(1+(/(-pxpx0)dx))))
(cond((=xh11)(lastsld))
((=xh12)(nexts
ld))
((=xh13)(setnil))
((=xh14)(setok))))
(defunlastsld())
(defunnextsld())
(defunsetnil())
(defunsetok())
如点在上半部分运行dq1,否则运行dq2while;defun图例主程序结束定义dq1子函数
点落在左面aorb为1
点在右面aorb为2;if
计算纵向序号计算图例图块名(由4部分连接组成)
dq1结束
定义dq2子函数
计算横向序号
运行lastsld子函数,向前翻页
运行nextsld子函数,向后翻页
运行setnil子函数,赋空退出
运行setok子函数,插入图例
定义lastsld子函数,略
定义nextsld子函数,略
定义setnil子函数,略
定义sitok子函数,略