Autolisp編程心得_第1頁
Autolisp編程心得_第2頁
Autolisp編程心得_第3頁
Autolisp編程心得_第4頁
Autolisp編程心得_第5頁
已閱讀5頁,還剩9頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、精品文檔Autolisp編程心得1. 養(yǎng)成良好的書寫習慣眾所周知,Lisp是一種表結(jié)構(gòu)語言,括號必須成對出現(xiàn),在調(diào)試時往往為遺漏了一個括號 大費周折,所以,養(yǎng)成一個好的編程習慣是學好Lisp所必須的。選擇一個較好的編輯器,這是一個基本條件,建議使用Visual Lisp編輯器或Lisplink等 專用編輯器,此類編輯器可以對函數(shù)突岀顯示。按Lisp ( DCL專有格式書寫,并經(jīng)常對程序進行“格式化”,及時發(fā)現(xiàn)語法錯誤,并有利于調(diào)試是查找錯誤。使用自定義函數(shù),并輔助以適當?shù)米⑨?,在較大程序中按功能使用自定義函數(shù)可以使得程序條理化。2. 函數(shù)中循環(huán)與轉(zhuǎn)移的使用在高級語言中一般有類似“goto ”的

2、語句實現(xiàn)轉(zhuǎn)移,在 AutoLisp中沒有轉(zhuǎn)移的函數(shù)。我們可 以使用自定義函數(shù)實現(xiàn)轉(zhuǎn)移,用if及cond輔助實現(xiàn)條件轉(zhuǎn)移。當我們需要實現(xiàn)在滿足一定條件時進行循環(huán)的功能,一般使用while函數(shù),但有時需要判斷的條件較復(fù)雜時,使用while函數(shù)往往不能實現(xiàn)或使得程序不夠簡潔。這時我們可以使用“轉(zhuǎn)移”, 將需要實現(xiàn)的功能作為(子)函數(shù),使用恰當,可以在程序中任意“轉(zhuǎn)移”。一般認為,當一段代碼在不同處重復(fù)使用時,我們才會使用子函數(shù)定義,其實,利用函數(shù)的更大的優(yōu)點是使得程序更加結(jié)構(gòu)化。這就使得我們不必拘泥于程序中的循環(huán)語句,而使用函數(shù)的循環(huán)調(diào)用,輔助適當?shù)呐袛?,實現(xiàn)“轉(zhuǎn)移”,如A-B-A。當然也可以進行自

3、身調(diào)用,構(gòu)成一個“標準的”循環(huán)。如例一中,“程序執(zhí)行完畢返回”與“空選返回”兩種情況如果使用循環(huán)語句,其條件是完全不同的,而將函數(shù)本身作為子函數(shù)調(diào)用,程序簡潔明了。3.i nitget函數(shù)中關(guān)鍵字 “(空格)的使用空格可以被用作關(guān)鍵字,一般多用來定義鼠標右鍵退岀。當用戶輸入函數(shù)不支持控制位(如entsel、nentsel、nentselp )時,可直接使用“ (initget )”。當用戶輸入函數(shù)支持控制位(如getpoint等)時,可使用 “ (initget 1 “)”禁止空輸入,而將回車等空輸入作為關(guān)鍵字使用。當同時使用其它關(guān)鍵字時,應(yīng)該將空格作為一系列關(guān)鍵字的最后一個,用“ (in i

4、tget C )” (兩個空格)調(diào)用,否則無效。見例一。*;例一(defu n ett_ct()(initget C );關(guān)鍵字“ C”及空格(setq s0 (entsel n設(shè)置顏色 C /選取文本:)(cond(=s0 C) (ett_col);(=s0 ) nil);(and (= (type s0) LIST);(=(cdr (assoc 0 (e ntget (car s0) TEXT);) )(ett_ct);)(t (ett_ct);)*轉(zhuǎn)設(shè)置顏色子函數(shù) 空格退岀選擇實體判別文本操作內(nèi)容編輯后返回選擇空選返回選擇有時需要進行復(fù)雜的判斷,使用如“ (=SO )”語句可能不能準確判

5、別輸入的空格關(guān)鍵字與空選擇,可以使用“ (=(type s0) STR) ”語句4. Lisp的暫停與while的特殊使用Lisp一般在交互輸入時才會暫停,如果只需要實現(xiàn)屏幕顯示暫停,可使用grread函數(shù),grread函數(shù)對所有合法的輸入設(shè)備均會作岀反應(yīng),有時我們只希望對鍵盤有反應(yīng),可使用while函數(shù)進行循環(huán)。*(pri nc nPress ENTER to con ti nue:)(while (/= (car (grread) 2)*while用于滿足一定條件的循環(huán),其標準語法為:(while testexpr expr.)其中expr解釋為“在testexpr 為nil之前要求值的一

6、個或多個表達式”,為可選項(在R14之前沒有方括號,但仍為可選項)。正常我們使用 while時,總會有expr項,更多的時候,我們是為了 expr項才會使用這種循 環(huán) 語句,所有我們往往有expr項是不可缺少的感覺。這里我們使用while函數(shù)的語法是 while函數(shù)的 特例,即沒有expr項的情況。如果希望對鼠標右鍵同時反應(yīng),可以使用:*(pri nc nPress ENTER to con ti nue:)(while (and (/= (setq a(car (grread) 2);鍵盤(/= a 11);鼠標右鍵(SHORTCUTMENU)(/= a 25);鼠標右鍵(SHORTCUTM

7、E1NU)*5. 輸入距離Lisp語言中輸入距離的函數(shù)為getdist ,但我們有時需要輸入負值,有時需要在輸入距離的同時得到角度,使用getdist函數(shù)就顯得無能為力,這時,我們可以靈活使用其它交互輸入函數(shù) 如getpoint、getcorner等,通過計算得到我們所需要的值。例二是一段輸入長度的同時得到默認角度的代碼,使用getpoi nt函數(shù)。*例二(setq pt0 (getpoint n直線基點:)pt1 (getpoint pt0 n直線長度:)dst (dista nee pt0 pt1) ang (an gle pt0 pt1)長度及角度可用鍵盤或鼠標定位計算長度計算默認角度a

8、ngl (geta ngle pt0 (streat n直線方向 :)*例三是可以按陣列方式輸入行列間距的代碼,輸入距離為正值,修改部分代碼可輸入負值, 使用getcorner函數(shù),同時使用initget 的控制位128。*例三(defu n lc_dist ()(in itget 128);(setq disr (getpoi nt n指定單位單元或輸入行間距:)(if (= (type disr) LIST);(prog n(in itget 1)(setq dis (getcorner disr n指定對角點 :);disc (abs (- (car dis) (car disr) ;d

9、isr (abs (- (cadr dis) (cadr disr) ;) ;)(if (= (type disr) STR);(if (setq dis (distof disr);(prog n(in itget 6)(setq disc (getdist n輸入列間距:);)(prog n;(pri nc n需要正數(shù)值或兩個二維角點。)(lc_dist)(prog n;(princ n需要正數(shù)值或兩個二維角點。)(lc_dist)允許任意輸入鼠標輸入鼠標輸入對角正值行距正值列距計算行列間距鍵盤輸入行距判斷輸入的是否距離輸入列距鍵盤輸入格式不符返回空輸入返回)*6. 數(shù)學運算函數(shù)的數(shù)量界限

10、在Lisp中對表中數(shù)據(jù)進行求和、求最大值等數(shù)學運算時,往往直觀的對表直接賦予運算函 數(shù),使用語句如“ (eval (cons MAX numlist)”,一般都可以進行計算,但當表中數(shù)據(jù)數(shù)量大于255 時,將會岀現(xiàn)錯誤“ bad argument value: does not fit in byte: 256”。對于這種情況,我們不必對數(shù)據(jù)表進行分段,可以直接使用函數(shù)apply,語法更簡單:(applyMAX numlist) 。apply可將數(shù)據(jù)表傳送給指定的函數(shù)進行求值而不受數(shù)據(jù)數(shù)量的影響。受表中數(shù)據(jù)數(shù)量影響的數(shù)學運算函數(shù)有:+、-、*、/、max min、logand及l(fā)ogior。7

11、. 選擇集與表選擇集是一種特殊結(jié)構(gòu)的表,只能通過特定的函數(shù)進行操作,但這些函數(shù)對大量重復(fù)的操作只能通過循環(huán)實現(xiàn),顯得力不從心,不能體現(xiàn)Lisp語言表結(jié)構(gòu)的優(yōu)越性。其實我們只要通過存取實體名或?qū)嶓w句柄,將它們存為一個普通結(jié)構(gòu)的表,完全可以通過常規(guī)表操作函數(shù)實現(xiàn)對實體的操作。例四是一段使用 apply、mapcar函數(shù)聯(lián)合求文本選擇集中文本基點最大y值得代碼,只是一個示例,如果結(jié)合 VL-sort函數(shù),可輕松實現(xiàn)對文本的排序。*;例四(setq sl nil i -1)(repeat (ssle ngth (setq ss (ssget (0 . TEXT)(setq i (1+ i)en (ss

12、 name ss i);sl (c ons en sl);)(setq maxy (apply max;(mapcar(lambda (x)(caddr (assoc 10 (en tget x);)sl)*選擇文本從選擇集中取岀文本構(gòu)造包含實體名的表求文本基點最大y值提取y值當然,選擇集也有其優(yōu)勢的一面,比如對選擇集中實體的刪除操作非常簡單、選擇集中的實體不會重復(fù)及選擇集可以與Acad命令交互使用等特征是一般表所不具備的,所以,編程時應(yīng)根據(jù)程序要求,靈活運用8. cal的使用與加載Acad隨機附帶了一些外部定義命令,其中cal (計算器)命令是最常用的命令之一,在加載gromcal.arx

13、后cal可以在Lisp程序中像其它函數(shù)一樣使用,這就使得我們在程序中對文本的 四則 運算處理變得簡單,如“ (cal 1+2/3) ”,其中字符串1+2/3可以從圖形的文本中提取,也可以是符合cal要求格式的任一字符串(詳見Acad聯(lián)機幫助)。需要注意的是,在Acad中g(shù)romcal.arx 只能加載一次,重復(fù)加載將使 Acad以外退岀(無提示)。需要使用cal函數(shù)的Lisp程序,應(yīng)在程序尾部加上以下代碼:*(if (or (= (type c:cal) LIST);R14使用(=(type c:cal) SUBR);R2000+使用)(arxload geomcal.arx)*9. Undo

14、處理一個完善的程序應(yīng)該有較好的岀錯處理,這是在所有Lisp教材上都提及的,但程序的Undo處理就說得很少或沒有提及。其實Undo處理對程序來說也是非常重要的,尤其對有較多輸岀的復(fù)雜程序而言,不能解決Undo問題,使用起來會極不方便。對于Undo問題的解決,一種方法是盡量少用或不用comma nd函數(shù),即不調(diào)用原始命令,這是一種較好的方法,但必須注意的是,一段程序必須至少有一次調(diào)用comma nd函數(shù),否則 Un do命令將取消程序運行前的前一次命令,解決的方法是在程序運行的起始位置加一個無謂的comma nd 女口 “ (comma nd color”)”。有時不使用comma nd函數(shù)不能達

15、到我們要求的一些功能,或使得程序過于復(fù)雜, 我們可能需要使用一些comma nd函數(shù)(原始命令),這是就應(yīng)該在程序中進行 Undo處理,即使用 Undo命令 的編組功能。例五是一段程序?qū)珏e函數(shù)與Undo處理的示例。* ;例五岀錯函數(shù)使用對話框時使用 岀錯函數(shù)恢復(fù) 系統(tǒng)變量恢復(fù) 岀錯函數(shù)恢復(fù)編組結(jié)束(defu n n ewerr (s);(if s(prog n(term_dialog);(if olderr (setq *error* olderr);(if oldvar (setvar . oldvar);(if olderr (setq *error* olderr);(comma nd

16、_.u ndo _e);Undo)(pr inc)(defu n c:my(/ )(setvar cmdecho 0)(comma nd _.u ndo _BE)(setq olderr *error* *error* n ewerr)(setq oldvar (getvar .)(setvar . )(setvar . oldvar)(setq *error* olderr)(comma nd _.u ndo _E)(pr inc);主程序(主函數(shù)) 取消命令回顯提示;Un do編組開始調(diào)用自定義岀錯函數(shù) 保存相關(guān)系統(tǒng)變量 設(shè)置系統(tǒng)變量 程序段恢復(fù)系統(tǒng)變量 恢復(fù)出錯函數(shù) 結(jié)束Undo命令編組

17、 取消程序返回值)*10. 程序調(diào)試時塊注釋的使用我們經(jīng)常會加上或屏蔽一段代碼輔助程序調(diào)試,此時最常用的是在需要暫時屏蔽的代碼前使用行注釋符號 “;”,對于較多的代碼就需要使用塊注釋“ ;| I; ”,如果一段代碼需要頻繁屏蔽,將行注釋與塊注釋組合使用,可以帶來極大方便。下圖是組合使用的示例。ll_j 附帶了這個的圖片(setq a 3) (princ a);| (if bCprinc (+ a 1)(princ (+ a 2)正常便用;(;l l;H(setq c nild(if bCprinc (+ s 寸 (princ (+ a 2) % -!l推看僮wn(setq d nilOCiF

18、bCprinc (+ a(princ (+ 占 2)昔取消-4呼(princ C* BVlisp編程技巧摘要(1).*)1. 如何獲取多義線上的所有頂點Code:(defu n C:getp (/ ent PLTYPE obj vtx vtxlst n ptlst)(vl-load-com)(setq ent (entsel n選取多線:n)(if ent(progn(setq PLTYPE (cdr (assoc 0 (e ntget (car e nt)(if (or (= POLYLINE PLTYPE) (= LWPOLYLINE PLTYPE)(prog n(setq obj (vl

19、ax-e name-vla-object (car en t)(setq vtx (vla-get-Coord in ates obj)(setq vtxlst (vlax-safearray-list (vlax-varia nt-value vtx)(setq n 0)(setq ptlst n il)(repeat (/ (le ngth vtxlst) 2)(setqptlst (append ptlst (list (list (nth n vtxlst) (nth (1 +n) vtxlst)(setq n (+ n 2)(if ptlst ptlst nil)(prompt n選

20、取實體不是多義線!);if);if).*)2. 在對話框的文本欄里輸入,怎樣讓它實時顯示為密碼“* ”?A.設(shè)計對話框時,控件的屬性中加:password_char = *;srt : dialog label =密碼“;:edit_box label =輸入密碼(&S):;key = password;password_char = *;fixed_width = true;width = 8;ok_only;(defu n c:srt ()(setq file name srt.dcl)(if ( (setq in dex_value (load_dialog file name) 0);

21、(progn(setq dlg name srt)(if (n ot (new_dialog dlg name in dex_value) (exit);(acti on _tile password (mypass)(action_tile ok (do ne_dialog 0)(start_dialog)(alert n不能載裝指定的DCL文件定義的對話框!);end IF(pri nc)(defu n mypass ()(setq a1 $value)B.使用DOSLib輸入密碼的函數(shù).*)3. 怎樣可以實現(xiàn)不用工具中的選項,來調(diào)岀屏幕菜單?;屏幕菜單切換(defu n C:pmme n

22、u ()(vl-load-com)(setq sd(vla-get-display(vla-get-prefere nces (vlax-get-acad-object)(if (= (vla-get-displayscree nmenu sd) :vlax-true)(vla-put-displayscree nmenu sd :vlax-false)(vla-put-displayscree nmenu sd :vlax-true)(vlax-release-object sd)(pri nc).*4. 怎么樣用 Vlisp來讀取AutoCAD中搜索路徑?(vla-get-supportp

23、ath(vla-get-files (vla-get-prefere nces或:(gete nv ACAD)n或:-rAi (acet-pref-supportpath-list)獲取支持路徑。.*裝載對話框顯視對話框(vlax-get-acad-object)5. 如何捕獲列表框(list_box )的雙擊操作?在 edit_box,list_box,image_button,slider 表示你執(zhí)行了什么操作。在list_box可在你的代碼中加入判斷:(action_tile listbox (fun1).)(defun fun 1()中,有一個$reason變量,用來中,雙擊的變量值是

24、 4。(if (= $reason 4).*6. 如何用 VLISP創(chuàng)建目錄?例如:A. (vl-mkdir c:hqd9639)B. (setq SYS (vlax-create-object Scripti ng.FileSystemObject)(setq FOLDER (vlax-i nvoke-method SYS CREATEFOLDER c:hqd9639).*7. 如何用(entsel)亮顯選擇物體?code:(if (setq en t (e ntsel nPick Object)(prog n(redraw (car ent) 3);(redraw (car ent) 4);不亮顯).*8. 如何隱藏選擇實體?code:(if (setq en t (e ntsel nPick Object)(prog n(redraw (car e nt) 1);隱藏實體;(redraw (car e nt) 2);顯示實體).*9. 狀態(tài)欄進度條的設(shè)計示例(defu n c:hqd1 ()已經(jīng)完成100)(acet-ui-progress (setq x 0)(while (List hqd).*11. 如何在CAD中插

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論