AutoLisp入門基礎教程(2)

這是AutoLisp入門基礎教程的第二部分。在教程的第一部分,我們掌握了如何在AutoCAD中加載一個AutoLisp程序,了解了如何使用defun來定義一個函數(shù)。在下面的內容中,我將結合一個實際工作中的簡單需求并編寫一個程序,以此來展示編程的思路,并重點講述常用的AutoLisp函數(shù)。

工作中有什么需求

在海工結構中,一些房間的墻壁經(jīng)常是由瓦楞板組成的。瓦楞板就是像瓦楞紙一樣的鋼板,如下圖所示。


瓦楞板就是這樣子的鋼板

在設計制圖階段,我們常常用一個曲折的多段線來表示這個瓦楞板,如下圖所示。圖中的幾個長度參數(shù)(x,y和h)決定了瓦楞板的形狀。一般的,為了畫一段長度的瓦楞板,需要確定該多段線的數(shù)十個的控制點。所以,若采用手工方法一個一個地確定控制點地位置來完成一個多段線,那么工作量是無比巨大的。正常人肯定不會這么干!在接觸AutoLisp之前,我也不知道瓦楞板是怎么畫的,但是又不得不畫(不畫就要被領導罵了),所以我就從別人的圖紙中復制一個長長的瓦楞板多段線,然后裁剪成合適的大小。


瓦楞板示意圖

復制別人圖紙中的東西確實是一個不錯的主意,但是如果瓦楞板的形狀尺寸改變了,就有可能無圖可抄了。我曾經(jīng)思考過很久如何快速地畫這樣一個瓦楞板,有同事說可以設置自定義線型(但是他竟然忘了如何設置了)。接下來,我們嘗試用AutoLisp編程來解決這個問題。

程序的構思

為了方便起見,先將瓦楞板的尺寸固定。程序的預期目標是,在輸入瓦楞板中軸線的起點(ps)和瓦楞板中軸線的終點(pe)后自動畫出一定長度的瓦楞板(即多段線)。從下圖可以看出,瓦楞板是一個循環(huán)的線段,一個循環(huán)單元由四個控制點組成(如圖中的 pa pb pc pd)。如何通過已知點(ps和pe)來確定這四個控制點的位置,是解決問題的關鍵。幸好,Autolisp語言提供了一些非常有用的函數(shù),如下:

(polar pt angle distance)
; 此函數(shù)將返回在pt點的某個方向(angle)上距離長度為distance的點
; angle 是從 x 軸開始的角度,以逆時針方為正
(angle p1 p2)
; 返回從p1到p2的射線與x軸正方向的夾角,單位是弧度
(distance p1 p2)
;返回p1與p2之間的距離

例如,pa在ps的(alpha+pi/2)角度上,距離為h/2;pb在pa的alpha角度上,距離為x;p_temp在pb的(alpha-pi/2)角度上,距離為h;pc在p_temp的alpha角度上,距離為y;pd在pc的alpha角度上,距離為x。這四個關鍵點就全部確定了(p_temp是為了表示方便而構造的變量)。使用polar函數(shù),把已上的陳述翻譯為AutoLisp語言,如下:

(setq 
    pa (polar ps (+ alpha (/ pi 2)) (/ h 2))
    pb (polar pa alpha x)
    p_temp (polar pb (- alpha (/ pi 2)) h)
    pc (polar p_temp alpha y)
    pd (polar pc alpha x)
)
程序中變量示意圖

如何AutoLisp中實現(xiàn)循環(huán)呢?方法之一是使用repeat函數(shù)

(repeat n exp...)
; n為正整數(shù),為循環(huán)的次數(shù)。exp...為循環(huán)執(zhí)行的表達式。

最終的程序

最后的程序,程序中的一些細節(jié)沒有講到。先寫這么多吧。

(defun c:wlb ()
    
    ;定義瓦楞板的尺寸
    (setq x 255 y 66 h 66)
    (while
        (and 
            (setq ps (getpoint "\n請輸瓦楞板的起點:"))
            (setq pe (getpoint "\n請輸瓦楞板的終點:"))
        )

        (setq 
            alpha (angle ps pe)
            dstc (distance ps pe)
            dstc_e (+ x y x y)
        )
        (setq nn (1+ (fix (/ dstc dstc_e))))
        (setq pa (polar ps (+ alpha (/ pi 2)) (/ h 2)))
        (setq oldsnap (getvar "osmode"))
        (setvar "osmode" 0)
        (command "pline")
        (repeat nn
            (setq 
                pb (polar pa alpha x)
                p_temp (polar pb (- alpha (/ pi 2)) h)
                pc (polar p_temp alpha y)
                pd (polar pc alpha x)
            )
            (command pa pb pc pd)
            (setq pa (polar pa alpha dstc_e))
        )
        (command "")
        (setvar "osmode" oldsnap)
        (prin1)
    )
)

以后接著寫吧。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容