AutoLISP入門教學.JPG (45140 bytes)


單元五:輕鬆快速的掌握AutoLISP設計技巧

 

一、AutoLISP 程式設計的四個步驟:

1.第一步驟:產生寫程式的動機、預期目標

2.第二步驟:構思程式流程、所需之LISP功能函數、相關變數訂定&提示訊息

3.第三步驟:利用文書軟體 (如記事本) 撰寫xxx.lsp程式

4.第四步驟:回到AutoCAD,載入AutoLISP程式以 (load"LSP主檔名") (load "LSP主檔名")

5.第五步驟:執行新的 AutoLISP 指令

 

二、透過簡單範例全程演練AutoLISP

1.第一步驟:動機、預期目標

如圖: 希望能在輸入『左下角點』、『矩形寬』、『矩形高』後,自動的將圖形依所給的條件畫出,如此一來,爾後畫這個圖就輕鬆愉快了!

lsp-5-1.GIF (2628 bytes)

2.第二步驟:構思程式相關變數訂定(如下圖)

lsp-5-2.GIF (3043 bytes)

圖記3.gif (439 bytes) 不可重複

圖記3.gif (439 bytes) 好記不會混淆

圖記3.gif (439 bytes) 適時的以分號『;』加上註解

(defun c:pbox()

;以下 pawwhh 值須由使用者輸入

(setq pa (請求輸入左下角點))

(setq ww (請求輸入矩形寬度實數值))

(setq hh (請求輸入矩形高度實數值))

;以下pbpcpd值須由程式依據pawwhh求出

(setq pb (依據相對極座標法求出pb點座標值))

(setq pc (依據相對極座標法求出pc點座標值))

(setq pd (依據相對極座標法求出pd點座標值))

;以下依據 papbpcpd 點畫矩形

(pline指令畫出矩形)

;以下mp1mp2mp3mp4值須由程式依據pawwhh

;& pbpcpd 值求出

(setq mp1 (求出 mp1 點座標值))

(setq mp3 (求出 mp3 點座標值))

(setq mp2 (求出 mp2 點座標值))

(setq mp4 (求出 mp4 點座標值))

;以下依據 mp1mp2mp3mp4 點畫出二條線

(line 指令畫出 mp1 mp3 的線)

(line 指令畫出 mp2 mp4 的線)

)

圖記3.gif (439 bytes) 本程式所需的 AutoLISP功能函數及其用法

(getpoint [基點] [提示]) <-- 請求輸入一個點座標

(getreal [提示]) <-- 請求輸入一實數

(polar 基點 弳度 距離) <-- 依極座標法取得另一座標點

其中『弳度值』之轉換為:

十進位角度

弳度值

十進位轉弳度公式

0 0 0
90 1/2p (/ pi 2) (* pi 0.5)
180 p pi
270 2/3p (* pi 1.5)
N p *N/180 (* pi (/ n 180))

(command "AutoCAD 指令" ...)  <--呼叫執行 AutoCAD 指令

注意: 指令及其副選項皆要用雙引號處理

假設 papbpcpd 皆為變數,其值為點座標

正確: (command "pline" pa pb pc pd "c")

錯誤: (command pline pa pb pc pd c)

原因: 指令 pline 及其副選項 c 皆沒用雙引號括住

錯誤: (command "pline" pa pb pc pd c)

原因: 副選項c (代表 close) 沒用雙引號括住,會被誤認為是

AutoLISP的變數名,但事實又沒有 c 這個變數

錯誤:(command "pline" "pa" "pb" "pc" "pd" "c")

原因:變數 papbpcpd 不須用雙引號括住

注意:副選項中,若使用 "" ,連續二個雙引號,代表按 [ENTER]

若想畫一條 pa pc LINE & 一條 pb pd LINE

正確: (command "line" pa pc "")

(command "line" pb pd "")

錯誤: (command "line" pa pc)

(command "line" pb pd)

圖記3.gif (439 bytes) 其他相關接近的功能函數...

(getdist [基點] [提示])ß請求輸入一段距離

(getint [提示]) ß請求輸入一整數值

(getcorner 基點 [提示]) ß請求輸入另一矩框對角點座標

(car 串列  ß傳回:串列中的第一個元素通常用來求x座標

(cadr 串列)   ß傳回:串列中的第二個元素通常用來求 y 座標

(caddr 串列)  ß傳回:串列中的第三個元素通常用來求z座標

 

3.第三步驟:利用 PE2CE 或記事本,撰寫 PBOX.LSP 程式並儲存 C:\LISPTOOL 目錄下!!!

(defun c:pbox()

;以下 pawwhh 值須由使用者輸入

(setq pa (getpoint "Enter Left/Low Point:"))

(setq ww (getreal "Width:"))

(setq hh (getreal "Height:"))

;以下pbpcpd值須由程式依據pawwhh求出

(setq pb (polar pa 0 ww))

(setq pc (polar pb (/ pi 2) hh))

(setq pd (polar pc pi ww))

;以下依據 papbpcpd 點畫矩形

(command "pline" pa pb pc pd "c")

;以下mp1mp2mp3mp4值須由程式依據pawwhh

;& pbpcpd 值求出

(setq mp1 (polar pa 0 (/ ww 2)))

(setq mp2 (polar pb (/ pi 2) (/ hh 2)))

(setq mp3 (polar pd 0 (/ ww 2)))

(setq mp4 (polar pa (/ pi 2) (/ hh 2)))

;以下依據 mp1mp2mp3mp4 點畫出二條線

(command "line" mp1 mp3 "")

(command "line" mp2 mp4 "")

)

4.第四步驟:回到 AutoCAD ,載入 AutoLISP 程式

圖記3.gif (439 bytes) 若您的AutoCAD『環境設定』中『支援檔搜尋路徑』有加上 c:\lisptool,則您可輕鬆載入 pbox.lsp 程式

      指令:(load"pbox") 傳回:c:pbox

      或  指令:(load "pbox") 傳回:c:pbox

      或  指令:(load "pbox.lsp") 傳回:c:pbox

圖記3.gif (439 bytes) 若您的AutoCAD『環境設定』中『支援檔搜尋路徑』並未加上 c:\lisptool,

則您載入 pbox.lsp 程式時,須包含程式所在路徑:

錯誤的載入:指令:(load "pbox")

會出現:無法開啟「pbox.lsp」做輸入

錯誤: 載入失敗

(LOAD "pbox")

*取消

正確的載入方式:

指令:(load "c:/lisptool/pbox") 傳回:c:pbox

或:指令:(load "c:\\lisptool\\pbox") 傳回:c:pbox

5.第五步驟:執行新的 AutoLISP 指令

指令:pbox       <-- 成功載入後,直接鍵入 pbox 指令

Enter Left/Low Point: <-- 請給一左下角點

Width: <-- 給一實數當寬度,例如100

Hieght: <-- 給一實數當高度,例如50

指令:nil

指令

 

三、PBOX.LSP 程式產生的問題 & 改良

1. 原程式雖是成功的載入執行了,但卻有以下幾點小問題:

問題1給完左下角點後,Width:』及『Height:』提示卻在同一行出現,應該一個提示各別一行才好???

ANS很簡單,只要做如下的改變,加入『\n』即可!!!

(setq ww (getreal "Width:"))à (setq ww (getreal "\nWidth:"))

(setq hh (getreal "Height:"))à (setq hh (getreal "\nHeight:"))

問題2希望給寬度及高度時,也能直接在螢幕上拉一段距離代替???

ANS很簡單,只要做以下的函數變動即可!!!

(setq ww (getreal "\nWidth:"))

改成 (setq ww (getdist pa "\nWidth:")) ß pa為參考基準點

(setq hh (getreal "\nHeight:"))

改成 (setq hh (getdist pa "\nHeight:")) ß pa為參考基準點

問題3給完寬度及高度值後,開始畫出所要的圖形,可是指令操作過程卻也跟著在『指令:』下一一配合出現著,不但影響速度,也沒有實質的意義,如何改善?

ANS很簡單,只要在程式一開始加入如下一行即可改善:

(setvar "cmdecho" 0) ß 設定變數cmdecho=0關閉指令回應

問題4畫完所要的圖形過程中,畫面出現了小十字點,還得用redraw指令清除,該如何使其不出現,但又不影響正常繪圖設定呢??? (R14環境blipmode內定值為0)

ANS很簡單,只要在程式一開始加入 (setvar "blipmode" 0) 即可有效壓抑小十字虛點出現!但須在程式結束前恢復設定 (setvar "blipmode" 1) ,才不會影響正常繪圖設定

問題5全部過程執行完後,在『指令:』後卻出現了空回應 nil,如何消除呢???

指令:pbox

Enter Left/Low Point:

Width:

Hieght:

指令:nil ß 就是這一行

指令

ANS很簡單,只要在程式結束前,加入一行 (prin1) 即可

問題6程式確認無誤後,想將所有變數均處理成『區域變數』,以免佔據記憶體

ANS很簡單,只要做如下的改變即可將 (defun c:pbox()

改成 (defun c:pbox(/ pa pb pc pd ww hh mp1 mp2 mp3 mp4)

問題7希望在 (load "pbox") 程式的回應訊息能有更多樣的變化

ANS很簡單,原回應是 c:pbox,請在程式結束後,再加入二列:

(prompt "********** << C:PBOX >> **********")

(prin1)

2. 改良後完整 PBOX.LSP 程式的全貌:

(defun c:pbox(/ pa pb pc pd ww hh mp1 mp2 mp3 mp4)

(setvar "cmdecho" 0)

(setvar "blipmode" 0)

;以下 pawwhh 值須由使用者輸入

(setq pa (getpoint "Enter Left/Low Point:"))

(setq ww (getdist pa "\nWidth:"))

(setq hh (getdist pa "\nHeight:"))

;以下pbpcpd值須由程式依據pawwhh求出

(setq pb (polar pa 0 ww))

(setq pc (polar pb (/ pi 2) hh))

(setq pd (polar pc pi ww))

;以下依據 papbpcpd 點畫矩形

(指令 "pline" pa pb pc pd "c")

;以下mp1mp2mp3mp4值須由程式依據pawwhh

;& pbpcpd 值求出

(setq mp1 (polar pa 0 (/ ww 2)))

(setq mp2 (polar pb (/ pi 2) (/ hh 2)))

(setq mp3 (polar pd 0 (/ ww 2)))

(setq mp4 (polar pa (/ pi 2) (/ hh 2)))

;以下依據 mp1mp2mp3mp4 點畫出二條線

(指令 "line" mp1 mp3 "")

(指令 "line" mp2 mp4 "")

(prin1)

)

(prompt "********** << C:PBOX >> **********")

(prin1)

 

四、本章結語: