• 72.00 KB
  • 2022-05-11 18:29:42 发布

lisp 语言在cad 道路设计中的各种应用

  • 9页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
第三章LISP语言在CAD道路设计中的各种应用3.1绘制平面任意函数曲线的AutoLISP程序设计在各个工程设计领域中,经常要绘制一些曲线,特别是平面曲线,如水工结构的溢流曲线、机械设计的齿轮渐开曲线等。在AutoCAD绘图软件中,可以将曲线上的点先计算好,再用线、多义线、样条曲线等方法绘制,这种方法需要进行大量计算,工作量较大,如果用EXCEL软件来辅助计算,可以减轻工作量;另外,可以针对具体的曲线类型,用AutoCAD内嵌的AutoLISP语言,实现边计算边绘制的功能。用这种方法绘制虽然快捷,但对于不同的曲线,则需编写同的AutoLISP程序,检查无误后才能运行,仍显繁琐。能否用统一的程序,来实现各种平面函数曲线的绘制,我们尝试利用AutoCAD中强大的表达式计算功能来实现这一目的。3.1.1平面函数曲线的类型和绘制方法平面函数曲线即是有简单函数表达式的曲线类型,可考虑经常遇到的4类:(1)直角坐标下形如y=f(x)的曲线;(2)直角坐标下的参数方程曲线;(3)极坐标下形如r=f(θ)的曲线;(4)极坐标下的参数方程曲线。其中,只需增加一个平凡方程x=x,参数方程(2)就可以包括相应的直接表达形式(1),同样(4)可以包括(3)。同时,极坐标形式可以通过:x=rcosθy=rsinθ转换为直角坐标表达。因此从本质上说,4种类型都可以互相转换,把它们分类的目的是尽量采用函数的通常表达形式,以便于使用。绘制时,参照曲线的手工绘制方法,需要给出曲线上的多个点,然后将它们连接起来。若给出的点间隔很小,直接用折线段相连就可很好模拟该曲线,如果间隔较大,可以用样条曲线连接,使之比较光滑。假设我们计算出足够多的点,简单用折线连接即可,为使该曲线成为一个整体,可用多义线的方式连接。关键的问题是,如何计算出曲线上点的坐标。由于曲线的函数表达式各种各样,不可能用统一的式子来表示。可以考虑从外部输入表达式,然后针对该表达式进行计算,给出相应结果,就能够解决点坐标的计算问题。但这个功能的实现比较困难,幸好AutoCAD为我们提供了CAL命令,可以对任意的表达式进行计算。该命令由函数库文件geomcal.arx提供,支持科学/工程计算器上的大多数标准函数,如三角函数、指数、对数等。若表达式中有变量,而该变量在程序中已设定了值,则按该值进行计算。由于该函数不是LISP内部函数,为使之可用,需要用ARXLOAD命令载入文件geomcal.arx,或者在命令行先输入CAL命令,由系统自动载入,这样,程序中就可以使用该函数了。总的程序定义为c:curve(),以便在AutoCAD命令行中与通常的命令一样使用。程序的总调用部分为:(arxload"geomcal.arx");载入提供表达式计算功能的ARX文件(vl-arx-import"c:cal);让命令c:cal能够使用(princ"(1)直角坐标下曲线y=f(x).n")(princ"(2)直角坐标下参数曲线x=f(i),y=g(i).n")(princ"(3)极坐标下曲线r=f(theta).n")(princ"(4)极坐标下参数曲线theta=f(i),r=g(i).n")(setqichoice(getint"选择绘制曲线类型:"));选择曲线类型(if(=ichoice1)(curve1));调用曲线绘制类型1(if(=ichoice2)(curve2));调用曲线绘制类型2 (if(=ichoice3)(curve3));调用曲线绘制类型3(if(=ichoice4)(curve4));调用曲线绘制类型4根据用户选择的曲线类型,转到相应的曲线类型绘制函数中,依次为直角坐标下的普通函数、参数方程,极坐标下的普通函数和参数方程。3.1.2直角坐标下函数y=f(x)的曲线绘制直角坐标下绘制函数曲线y=f(x)定义为AutoLISP子程序curve1,该子程序没有传入传出参数。程序的第一个步骤是读入有关的参数和控制变量。首先读入y=f(x)的表达式,然后输入自变量x的变化范围[low,up],接着根据模拟精度,输入曲线剖分数目steps,x的变化步长即为step=(up-low)/steps,该步骤相应的AutoLISP程序如下:(setqfuny(getstring"y=f(x)的表达式:"))(setqlow(getreal"x的下限值:"))(setqup(getreal"x的上限值:"))(setqsteps(getint"剖分数目:"))(setqstep(/(-uplow)steps))接下来就开始曲线的绘制,首先启动绘制多义线的命令,接着自变量x从下限值开始,由f(x)的表达式计算y坐标值,将该点的坐标输入到命令行,得到曲线的起点,然后自变量x递增一个步长,计算下一个坐标点,曲线连接到该点,如此直到剖分数目结束,就完成了整个曲线的绘制,最后用一个空格退出多义线命令。相应的AutoLISP程序如下:(command"pline");启动多义线命令(setqii0);循环变量ii设初值(setqxlow);自变量x设初值(while(<=iisteps);控制循环数目(setqy(c:calfuny));对表达式进行计算,得到y坐标值(command(listxy));输入计算出的点坐标(setqii(+1ii));循环变量ii增加1(setqx(+xstep));自变量x递增一个步长(command"");退出多义线命令3.1.3直角坐标下参数方程曲线绘制直角坐标下参数方程与直接函数表达不同的是,引入参变量,坐标x和y都表达为该参变量的函数,这样,能够表示的函数更灵活多样,形式如下:在曲线绘制时,只需要将变量改为参变量,坐标计算时对x、y坐标都用表达式计算即可,相应的AutoLISP程序如下:(setqii0);循环变量ii设初值(setqilow);参变量i设初值(while(<=iisteps);循环控制(setqx(c:calfunx));由x=f(i)计算坐标x(setqy(c:calfuny));由y=g(i)计算坐标y(command(listx1y1));向命令行输入点坐标(setqii(+1ii));循环变量ii增加1(setqi(+istep));参变量i递增一个步长3.1.4极坐标下函数r=f(θ)曲线绘制极坐标下函数r=f(θ)的不同之处在于输入点的坐标时,需要用极坐标输入方式,如20<30,表示极径为20,角度为30°,可以将得到的坐标值转换为字符串,再用角度符号“<”连接起来,输入到命令行。也可以用另外一个简便方法,即利用极坐标和直角坐标之间的转换关系,变换到直角坐标后输入到命令行,该方法对应的AutoLISP程序如下:(setqii0)(setqelow);设置极角θ的初始值 (while(<=iisteps)(setqr(c:calfuny));计算极径r(setqx(c:cal"r*cos(e)"));由极径r和极角θ转换为直角坐标下的x值(setqy(c:cal"r*sin(e)"));由极径r和极角θ转换为直角坐标下的y值(command(listxy))(setqii(+1ii))(setqe(+estep));对极角递增一个步长3.1.5极坐标下参数方程曲线绘制极坐标下参数方程曲线的绘制,同直角坐标下的参数方程曲线绘制是类似的,即增加一个用参变量表达的极角θ的计算,相应的AutoLISP程序如下:(setqii0)(setqilow);设置参变量i初值为下限值(while(<=iisteps)(setqe(c:calfunx));由表达式计算极角θ(setqr(c:calfuny));由表达式计算极径r(setqx(c:cal"r*cos(e)"))(setqy(c:cal"r*sin(e)"))(command(listxy))(setqii(+1ii))(setqi(+istep));参变量递增一个步长3.1.6总结利用AutoCAD的表达式计算功能,编写出绘制平面函数曲线的AutoLISP程序,根据外部输入的函数表达式,迅速绘制出函数曲线,且可以灵活控制曲线的模拟精度,避免了以往每绘制一种曲线都要重新编写程序的麻烦,使用起来十分方便。可以参照本文的做法,绘制三维空间曲线或其他更复杂的曲线,或将表达式计算功能应用到其他设计环境中。3.2基于AutoCAD的线路缓和曲线的自动绘制3.2.1背景铁路与公路的线路在定线中,由于受地形、地物或其他因素限制,需要改变方向。在改变方向处,相邻两直线间要求用曲线连接起来,以保证行车顺畅安全这种曲线称平面曲线。铁路与公路线上采用的平面曲线主要有圆曲线和缓和曲线,如图1所示。圆曲线是具有一定曲率半径的圆弧;缓和曲线是连接直线与圆曲线的过渡曲线,其曲率半径ρ由无穷大(直线的半径)逐渐变化为圆曲线半径R。在铁路干线线路中都要加设缓和曲线。由于缓和曲线上各点的曲率半径及圆心均为变数,所以在绘制线路平面图时,利用绘图工具无法准确、有效地绘制出缓和曲线。目前大多数采用曲线板近似描绘缓和曲线;或者是在AutoCAD中,用多段线近似代替缓和曲线。这些方法作图不准确,而且作图效率低。笔者在实践中,利用AutoLISP编程,实现了基于AutoCAD的缓和曲线加圆曲线的自动绘制。3.2.2缓和曲线的主点及要素1.缓和曲线的形成图2(b)是没有加设缓和曲线的圆曲线。缓和曲线是在不改变直线段方向和保持圆曲线半径不变的条件下,插入到圆曲线与直线段之间的平面曲线。为了在圆曲线与直线之间加入一段缓和曲线l0,原来的圆曲线需要在垂直于其切线的方向上移动一段距离p(见图2(a)),因而圆心就由O移动到O1,而原来的半径R保持不变。2.缓和曲线的主点ZH——直缓点,即直线与缓和曲线的分界。点;HY——缓圆点,即缓和曲线与圆曲线的分界点;QZ——曲中点,即圆曲线的中点;YH——圆缓点,即圆曲线与缓和曲线的分界点;HZ——缓直点,即缓和曲线与直线的分界点;JD——两直线延长线的交点。3.缓和曲线的综合要素T——切线长,即交点至直缓点或缓直点的直线长度; R——圆曲线半径;L——曲线(圆曲线+缓和曲线)的长度;0l——缓和曲线的长度;E0——外矢距,即交点至曲线中点的距离(JD至QZ的距离)α——转向角,即直线转向角;0β——缓和曲线的切线角,即缓圆点HY(或圆缓点YH)切线与直缓点(或缓直点HZ)切线的交角,亦即圆曲线HY→YH两端各延长20l部分所对应的圆心角;m——切垂距,即ZH(或HZ)至自圆心O1向ZH点或HZ点的切线作垂线垂足的距离。p——圆曲线移动量,即垂线长与圆曲线半径R之差。在上述要素中,α,R,l0为已知要素(可根据实际测定或在线路设计时选定),其他要素需根据α,R,l0求得。它们的关系为4.缓和曲线方程式由于缓和曲线的曲率半径ρ从直线的曲率半径∝(无穷大)逐渐变化到圆曲线的曲率半径R,在曲线上任一点P的曲率半径ρ与曲线的长度l成反比,如图3所示,以公式表示为式中C为常数,称曲率半径变更率。设β为缓和曲线上任一点的切线角,x,y为这一点的坐标,ρ为这一点上曲线的曲率半径,l为从ZH点到这点的缓和曲线长(见图3)。则有图3缓和曲线上任一点的坐标5.缓和曲线常数m——切垂距,即ZH(或HZ)至自圆心。O1向ZH点或HZ点的切线作垂线垂足的距离。p——圆曲线移动量,即垂线长与圆曲线半径R之差。3.2.3圆曲线加缓和曲线的绘制1.绘制缓和曲线假设两直线的转角为逆时针方向,则自原点(ZH)至交点(JD)为第1条直线;自交点(JD)至缓直点(HZ)为第2条直线。前面已经建立了缓和曲线的方程式和缓和曲线常数的计算式。缓和曲线方程式的坐标系为直角坐标系,其坐标原点为直缓点(ZH),x轴与直缓点(ZH)的切线方向一致。为了根据方程式计算缓和曲线上的点的坐标并绘制缓和曲线,需要使AutoCAD的坐标系与缓和曲线的坐标系重合。为此,单击“UCS”工具栏中的“对象UCS”按钮,并在靠近交点(JD处拾取第2条直线,此时UCS坐标系的原点位于交点,且x轴与第2条直线重合,方向由交点(JD)指向缓直点(HZ),如图5所示(此操作在执行程序前完成)。然后再将UCS坐标系绕z轴旋转-α角,此时UCS的x轴与第1条直线重合,且其方向与缓和曲线所在坐标系的x轴方向一致,如图6所示;再将UCS坐标系的原点平移到直缓点(ZH),直缓点在当前UCS中的坐标为(-TL,0)。此时UCS与缓和曲线的坐标系完全重合,如图7所示。于是可以利用缓和曲线方程式,计算缓和曲线上的点的坐标,并利用样条曲线命令将各点连成光滑的曲线。此过程可以通过循环语句来完成。AutoLISP程序代码如下:(defunc:hhqx(/RL0alphaqxmpTLE0X0y0alpha1LL2L5P0hhqx1hyxhyyyhxyhyqzxqzyp1)(setqR(getreal"n输入圆曲线的曲率半径R:"))(setqrL0(getreal"n输入缓和曲线长度L0:"))(setqalpha(getreal"n输入转向角α:"))(setqalpha1(/(*alphapi)180));求缓和曲线常数:m,TL,p,0x,0y(setqm(-(/L02)(/(*L0L0L0)(*240(*RR)))))(setqp(/(*L0L0)(*24R)))(setqTL(+m(*(+Rp)(/(sin(/alpha12))(cos(/alpha12)))))) (setqx0(-L0(/(*L0L0L0)(*40RR)))y0(/(*L0L0)(*6R)));计算缓圆点的坐标(command"ucs""_z"(-0alpha))(command"ucs""or"(list(-0TL)0))(setqL0.)(command"spline")(while(:311.8101,99.2371指定下一点或〔闭合(C)/拟合公差(F)〕<起点切向>:336.9780,108.6801指定下一点或〔闭合(C)/拟合公差(F)〕<起点切向>:383.6319,133.7401指定下一点或〔闭合(C)/拟合公差(F)〕<起点切向>:指定起点切向:232.9548,92.1117指定端点切向:383.6319,133.7401在这里我们要注意起点切向和端点切向的选择,它们分别是1点坐标和5点坐标。到此我们已把含缓和曲线的平曲线部分绘制完成。3.5.3里程桩的标注和图形的文字注解我们要在1、2、3、4、5点,5个主点绘制5个曲线主点桩,可以分为以下几个步骤进行。1.绘制曲线路段的法线①我们可以利用偏移命令(Offset)把缓和曲线向曲线弯道内侧作偏移,偏移距离为5个单位。步骤如下:命令:_offset指定偏移距离或[通过(T)]<通过>:5选择要偏移的对象或<退出>:②我们用点命令(Point)绘制出1、2、3、4、5点。③把对象捕捉模式中的垂足捕捉模式和结点捕捉模式选中。2.曲线主点桩和里程标注利用绘图菜单下的文字命令中的单行文字命令,以1点桩号标注为例,具体操作步骤如下:命令:_dtext指定文字的旋转角度<0>:90输入文字:k10+119.067注意,文字的起点选在适当的位置,旋转角度选择合适的角度。2、3、4、5点的桩号标注与其相同。标注效果中的1、2、3、4、5点上面的文字标注。以上事例为AutoCAD在公路设计中的一个例子,我们应该更加努力的去思考和研究如何利用CAD去解决公路设计中的现实问题。3.6Visuallisp程序在土方断面图绘制上的应用3.6.1前沿与介绍 AutoCAD是使用十分广泛的计算机辅助设计绘图软件,面世以来,其丰富的绘图功能,强大的编辑功能和良好的用户界面深受广大工程设计制图人员的普遍欢迎。然而大量重复性工作又使得工程设计制图人员为之头疼。CAD系统提供软件的界面、环境、核心算法、数据库及设计需要相关的、较专业的支持软件,而在工程测量中CAD无法方便的绘制工程所需的断面图、示意图等。Visuallisp是由Autodesk公司开发的一种lisp程序语言,Visuallisp功能非常强大,除了本身提供丰富的功能函数外,还可以使用Activex进行组件方式的编程,充分使用第三方所提供的Activex,使得Visuallisp几乎是无所不能,如可以进行数据库访问、生成Word文档、Excel报表等等。Visuallisp是个可视化的确LISP语言开发环境,适合开发小型规模的应用程序软件。3.6.2程序设计与实现1.简介该程序的运行是以AutoCAD2005为平台,利用Visuallisp语言进行的程序开发,读取我院自行开发的断面法土方量计算程序的断面数据,实现断面序号、断面桩号、原现断面图的快速自动绘制。2.断面数据格式394断面个数1,0.0,6,4断面序号,断面桩号,原断面个数,现断面个数18.59,307.6高程,距离(原断面min)18.74,317.0高程,距离17.56,317.017.56,326.019.11,326.019.11,330.0高程,距离(原断面max)19.11,330.0高程,距离(现断面max)19.50,329.6高程,距离19.50,307.518.59,307.6高程,距离(现断面min)2,8.0,2,2断面序号,断面桩号,原断面个数,现断面个数18.59,310.018.59,331.019.50,331.019.50,310.03.设计思路4.源程序(DEFUNC:dmv()(setvar"cmdecho"0)(setqfd(open(getfiled"打开数据""""dat"16)"R"))(setqn(READ-LINEFD)n(readn)a0jgjsnilpt1nilpt2nilabcnil) (setqi0j0)(SETQABC(GETINT"n注记桩号(2)都要注记(3)"))(if(=abcnil)(setqabc1))(alert"距离比例尺为1:1000,高程比例要自己设定")(setqbl(getint"n请输入高程比例尺<500>"))(if(=blnil)(setqbl500))(setqjg(getint"n请输入断面间隔<30>"))(if(=jgnil)(setqjg30))(setqpt0(getpoint"n请输入断面图的基点<0,0>:"))(if(=pt0nil)(setqpt0(list00))(setqpt0(getpoint)))(setqbln(/1000bl))(while(and(>=i0)(<=in))(setqxx(READ-LINEFD))(setqxx1(read(strcat"("xx")")))(setqa2)(if(/=(nth2xx1)nil)(progn(setqdmh(nth0xx1)zh(nth1xx1)ydms(nth2xx1);;原断面数;;xdms(nth3xx1);;现断面数;;j0h0);;H为现断面的循环数;;(setqa0)(setqi(nth0xx1)))(progn(if(