您當(dāng)前的位置:主頁(yè)>>AutoCAD>>AutoCAD二次開(kāi)發(fā) |
AutoCAD中特定角度及長(zhǎng)度捕捉的實(shí)現(xiàn)方法 一、引言 在AutoCAD中的角度捕捉只有當(dāng)正交狀態(tài)打開(kāi)時(shí)的直和水平方向,對(duì)于其他特殊角度無(wú)能為力;另外,其網(wǎng)點(diǎn)捕捉也是相對(duì)于X軸和Y軸,無(wú)法實(shí)現(xiàn)其他方向的特殊長(zhǎng)度捕捉,給繪圖帶來(lái)極大的不方便。 在應(yīng)用 AutoCAD 進(jìn)行設(shè)計(jì)制圖的操作中, LINE 和POLYLINE 是使用頻率最高的兩個(gè)命令, 經(jīng)常要遇到在某些特定角度上繪制特定長(zhǎng)度的簡(jiǎn)單線或復(fù)合線的情況,因而實(shí)現(xiàn)這兩個(gè)捕捉對(duì)提高AutoCAD 作圖效率很有實(shí)用價(jià)值。 二、方法原理 所謂角度捕捉,是指當(dāng)十字光標(biāo)在某一角度α的一定范圍內(nèi)選取一點(diǎn)時(shí),該點(diǎn)自動(dòng)落在該α角度線上;當(dāng)我們?cè)O(shè)定捕捉角度為α?xí)r,將會(huì)以基準(zhǔn)點(diǎn)作為原點(diǎn)、自X軸正方向出發(fā),將整個(gè)屏幕劃分為[360/α]個(gè)區(qū)間,則NXα角度就是角度捕捉線,其中,0≤N≤[360/α],[360/α]表示不大于360/α的整數(shù)。 所謂長(zhǎng)度捕捉,是在角度捕捉的基礎(chǔ)上,在某一角度線上有一系列捕捉點(diǎn),該系列點(diǎn)離基準(zhǔn)點(diǎn)的距離為捕捉長(zhǎng)度的正整數(shù)倍,當(dāng)選取直線上的一點(diǎn)時(shí),落點(diǎn)自動(dòng)落到離其最近的捕捉點(diǎn)上。 實(shí)現(xiàn)特定角度和長(zhǎng)度捕捉的關(guān)鍵點(diǎn)是:當(dāng)十字光標(biāo)(即十字交叉線)移動(dòng)時(shí),程序要隨時(shí)跟蹤其交叉點(diǎn)的位置,并將該位置與用戶(hù)所設(shè)定的捕捉角度與長(zhǎng)度對(duì)應(yīng)起來(lái),從而計(jì)算出在該角度上的落點(diǎn)。 以下舉例說(shuō)明該兩個(gè)捕捉的實(shí)現(xiàn)過(guò)程: 假定捕捉角度為α=30°,捕捉長(zhǎng)度為L(zhǎng)。 當(dāng)十字光標(biāo)在任意的某一區(qū)間內(nèi)移動(dòng)時(shí),比如在第5區(qū)間(120°~150 °)內(nèi)移動(dòng)時(shí),此時(shí),落點(diǎn)只能在120°或150°線上(該線在圖中并不直接顯示),該兩根角度線的中心線為135°。當(dāng)十字光標(biāo)的中心點(diǎn)處在120°~135°之間時(shí), 則落點(diǎn)應(yīng)在120°線上,該落點(diǎn)的具體位置為由十字光標(biāo)的中心點(diǎn)向120°線作垂線來(lái)獲得,其交點(diǎn)D(稱(chēng)為垂點(diǎn))即為落點(diǎn),為直觀起見(jiàn),此時(shí)由基準(zhǔn)點(diǎn)(此處為O點(diǎn))向落點(diǎn)作一橡筋拖曳線,該橡筋拖曳線隨十字光標(biāo)的移動(dòng)而相應(yīng)移動(dòng),顯示出拖動(dòng)過(guò)程(見(jiàn)圖1);同樣,當(dāng)十字光標(biāo)的中心點(diǎn)處在135°~150°之間時(shí),則落點(diǎn)應(yīng)在150°線上,并顯示相應(yīng)的橡筋拖曳線。該橡筋拖曳線并不是真正的線段, 只是用XOR墨水繪制的一個(gè)向量,當(dāng)用XOR墨水重新繪制一遍該向量時(shí),該向量將從屏幕上消失,這就是本程序?qū)崿F(xiàn)光標(biāo)拖動(dòng)的原理。 落點(diǎn)落在某一捕捉角度線上時(shí),還得落在捕捉長(zhǎng)度L 的整數(shù)倍的點(diǎn)(稱(chēng)為捕捉點(diǎn))上,還是針對(duì)圖1,其垂點(diǎn)必然處于某兩個(gè)捕捉點(diǎn)A與B之間,設(shè)A與B的中點(diǎn)為C,當(dāng)D處于A與C之間時(shí),落點(diǎn)應(yīng)為A;當(dāng)D處于C與B之間時(shí),落點(diǎn)應(yīng)為B (見(jiàn)圖1)。其中: -- -- OA = n XL ; OB = (n + 1) XL n: 非負(fù)整數(shù)。 L: 捕捉長(zhǎng)度。 此時(shí),程序通過(guò)一定的操作將在屏幕的最上面的坐標(biāo)提示行準(zhǔn)確地顯示落點(diǎn)相對(duì)基準(zhǔn)點(diǎn)的偏移長(zhǎng)度和偏移角度。用戶(hù)可以滑動(dòng)鼠標(biāo)準(zhǔn)確捕捉到目標(biāo)點(diǎn)。 至此,已實(shí)現(xiàn)某些特定角度及長(zhǎng)度的捕捉。為了滿(mǎn)足在程序執(zhí)行過(guò)程中能隨時(shí)更改捕捉角度和捕捉長(zhǎng)度的需要,本程序還增加了相應(yīng)的模塊;另外,本程序中嵌入了窗口放縮功能模塊,通過(guò)點(diǎn)取下拉菜單中窗口及漫游子菜單,方便了各種作圖的需要。 三、源程序清單 ;; OS.LSP源程序 ;;err(),出錯(cuò)處理子程序 (defun err ( msg) (if (/= msg "Function cancelled") (princ(strcat "\nError:" msg)) ;打印錯(cuò)誤內(nèi)容 ) ;for if (setq *error* olderr) (setvar "cmdecho" scmd) (setvar "osmode" cosmode) (setvar "coords" ccoords) (princ "n\n\t --多謝使用角度捕捉2.0版,程序非正常結(jié)束--!\n") (princ) ) ;for defun err ;; ant(),設(shè)定捕捉角度子程序 (defun ant ( / ang0 ang1 ) (setq ang0 (* an0 (/ 180 pi)) ) (princ (strcat "\n請(qǐng)輸入捕捉角度:<" (rtos ang0) ">_")) (INITGET 4) (setq ang1 (getreal)) (if (not (null ang1)) (setq an0 (* ang1 (/ pi 180))) ) (princ "\n F2/F3/F4/F5/ESC/Return /下一點(diǎn):") ) ;for defun ant ;; leng(),設(shè)定捕捉長(zhǎng)度距離子程序 (defun leng ( / leng0 leng1 ) (setq leng0 len0) (princ (strcat "\n 請(qǐng)輸入捕捉長(zhǎng)度距離:<" (rtos leng0) ">_")) (INITGET 4) (setq leng1 (getreal)) (if (not (null leng1)) (setq len0 leng1 ) ) (princ "\n F2/F3/F4/F5/ESC/Return /下一點(diǎn):") ) ;for defun lent ;; field(),判斷十字光標(biāo)所在區(qū)間,并投影到相應(yīng)的捕捉角度線上 (defun field ( ps pe ang0 / ang1 n ) (setq ang1 (angle ps pe)) (setq n (fix (+ ( / ang1 ang0) 0.5))) (setq ang2 (* ang0 n)) );for defun ;; endp(), 十字光標(biāo)投影到相應(yīng)的捕捉角度上后,以用戶(hù)設(shè)定的長(zhǎng)度 ;; 捕捉計(jì)算落點(diǎn) (defun endp ( ps pe ang0 / p1 p2 p3 p4 dis ) (setq p1 ps p2 (polar ps ang0 1) p3 pe p4 (polar pe (+ ang0 (/ pi 2)) 1) ) (setq pend (inters p1 p2 p3 p4 nil)) (setq dis (distance ps pe)) (if ( / = len0 0) (setq dist (* (fix (+ (/ dis len0) 0.5)) len0)) ;else (setq dist dis) ) ;for if (setq pend (polar ps ang0 dist)) ) ;for defun endp ;; drag(), 對(duì)上一次顯示的拖曳線進(jìn)行"或"操作,使其從屏幕上消失, ;; 并繪制下一次拖曳線 (defun drag ( pold1 pold2 pold3 / ) (if ( / = b2 4) (progn (grdraw pold1 pold2 -1 0) (grdraw pold2 pold3 -1 0) ) ) ;for if (grdraw pstart pend -1 0) (grdraw pend pframe -1 0) ) ;for defun drag ;; coord(), 在屏幕的最上一行的坐標(biāo)欄顯示長(zhǎng)度和角度 (defun coord ( / str leng1 leng0 ang0) (setq ang0 (* ang2 (/ 180 pi)) ) (setq str (strcat (rtos dist) ">" (rtos ang0))) (grtext -2 str) ) ;for defun coord ;; init(), 對(duì)程序進(jìn)行初始化 (defun init ( / ) (setq scmd (getvar "cmdecho"));保留原命令回顯方式 (setq ccoords (getvar "coords"));保留原坐標(biāo)顯示方式 (setq cosmode (getvar "osmode")) (setq olderr *error* *error* err) ;出錯(cuò)處理 (setvar "cmdecho" 0);不回顯 (setvar "coords" 0) ;不顯示坐標(biāo) (setvar "osmode" 0 ) ;取消捕捉 (setq b 0 b1 0 c '(0 0) ) (setq pstart (getpoint "\n 請(qǐng)輸入直線第一點(diǎn):")) (if (or (null an0 ) (< an0 0) (not (numberp an0))) (progn (setq an0 (/ pi 6)) (ant) ) ) ; for if (if (or (null len0 ) (< len0 0) (not (numberp len0))) (progn (setq len0 1) (leng) ) ) ;for if (if (null len0) (leng)) (princ "\n F2/F3/F4/F5/ESC/Return /下一點(diǎn)::") (setq a (grread 2 nil)) (setq pframe (cadr a)) (field pstart pframe an0) (endp pstart pframe ang2) (grdraw pstart pend -1 0) (grdraw pend pframe -1 0) (setq plast pframe polde pend) (setq b (car a)) ) ;for defun init ;; home(), 設(shè)置退出程序的控制變量 (defun home ( / ) (setq b 3) (setq b1 1) ) ;for defun home ;; pull(), 接受用戶(hù)輸入控制子程序 (defun pull ( / ) (setq b1 0) (while (/= b 3) (progn (setq a (grread 2 nil)) (coord) (if (and (= b 2) (= b2 4)) (setq b 4)) (setq b2 b) (setq b (car a)) (cond ((or (= b 5) (= b 12) );只移動(dòng)十字光標(biāo)時(shí) (progn (setq pframe (cadr a)) (field pstart pframe an0) (endp pstart pframe ang2) (if (>= (distance plast pframe) 0.1) (progn (drag pstart polde plast) (setq plast pframe polde pend) ) ;for progn ) ;for if ) ;for progn ) ;for cond1 ( (= b 3);用鼠標(biāo)在屏幕上點(diǎn)取一點(diǎn)時(shí) (progn (setq pframe (cadr a)) (field pstart pframe an0) (endp pstart pframe ang2) (if (>= (distance plast pframe) 0.1) (progn (grdraw pstart polde -1 0) (setq plast pframe polde pend) ) ;for progn ) ;for if ) ;for progn ) ;for cond1 ((= b 2);鍵盤(pán)輸入 (progn (setq c1 (cadr a)) (cond ((= c1 138) (ant)) ;F2 ((= c1 139) (leng)) ;F3 ((= c1 140) ;F4 (progn (setq b2 4) (command"zoom" "0.7x") ) ) ;for (= c1 140) ((= c1 141) ;F5 (progn (setq b2 4) (command"zoom" "1.4x") ) ) ;for (= c1 141) ((= c1 13) (home)) ((= c1 27) (home)) (T (princ "\n 未定義的鍵")) ) ;for cond (princ "\n F2/F3/F4/F5/ESC/Return /下一點(diǎn):") );for progn );for (cond (= b 2)) ((= b 4);點(diǎn)取下拉菜單時(shí) (progn (setq c1 (cadr a)) (princ "\n") (cond ((= c1 6005) (progn (command"zoom" "w") (princ "\n 第一角點(diǎn):") (command pause) (princ "\n 第二角點(diǎn):") (command pause) ) ) ;for (= c1 6005) ((= c1 6007) (command"zoom" "p" )) ((= c1 6008) (command"zoom" "a" )) ((= c1 6011) (progn (command"pan") (princ "\n 第一參考點(diǎn):") (command pause) (princ "\n 第二參考點(diǎn):") command pause) ) ) ;for (= c1 6011) ;;else (T (princ "\n 未定義的菜單")) ) ;for cond (princ "\n F2/F3/F4/F5/ESC/Return /下一點(diǎn):") ) ;For PROGN ) ;for (cond (= b 4)) (T (home) ) ;for else ) ;for cond ) ;for progn ) ;for while ) ;for defun pull ;; draw() , 繪制直線子程序 (defun draw ( / ) (while (/= b1 1) (progn (if (= b 3) (progn (command"line" pstart pend "") (princ "\n F2/F3/F4/F5/ESC/Return /下一點(diǎn):") (setq b 0 b1 1) (setq pstart pend) );for progn ); for if (pull) ) ;for progn ) ;for while (grdraw pstart pend -1 0) (grdraw pend pframe -1 0) ) ;for defun draw ;;;;主程序 (defun c:os ( / b b1 b2 c pstart pend pframe plast ang2 dist scmd ccoords olderr cosmode ) ;;; an0 len0 are defined out program (init) (draw) (princ "\n") (command"redraw") (setq *error* olderr) (setvar "cmdecho" scmd) (setvar "osmode" cosmode) (setvar "coords" ccoords) (princ "\n\n\t ------角度捕捉2.0版------\n") (princ "\n\n\t**寧波大學(xué)建筑設(shè)計(jì)研究院--程建華,1996**\n") (princ) ) ;for defun os 四、程序的安裝與使用 1. 程序的安裝 以下三種裝載方式,用戶(hù)任選一種即可: 在AutoCAD環(huán)境下,將OS.LSP拷至當(dāng)前目錄,再執(zhí)行(LOAD"OS")即可裝載OS.LSP。也可先將OS.LSP拷至\ACAD\SUPPORT\子目錄下,再在\ACAD\SUPPORT\ACADR12.LSP或ACADR13.LSP中加入下面一句語(yǔ)句實(shí)現(xiàn)啟動(dòng)AutoCAD時(shí)自動(dòng)裝載: (AUTOLOAD "OS" '("OS")) 也可將OS.LSP拷至\ACAD\SUPPORT\子目錄下,在\ACAD\SUPPORT\\子目錄下的菜單文件ACAD.MNU中的合適位置加上下面的一句語(yǔ)句,即可直接在菜單中點(diǎn)取角度捕捉操作: · · · [角度捕捉]^c^c(load"c:/acad/support/os.lsp") os · · · 2. 程序的使用 在一幅圖中第一次使用該程序時(shí),需要用戶(hù)輸入捕捉角度和捕捉長(zhǎng)度,第二次調(diào)用本程序時(shí),程序可自動(dòng)采用上一次最后設(shè)定的捕捉角度和長(zhǎng)度作為默認(rèn)值。然后,程序需要用戶(hù)選擇輸入一點(diǎn)作為基準(zhǔn)點(diǎn),此時(shí)命令行提示: F2/F3/F4/F5/ESC/Return /下一點(diǎn): 用戶(hù)根據(jù)該提示可任選其中的一種操作,具體解釋如下: ① 按F2鍵重新設(shè)定捕捉角度; ② 按F3鍵重新設(shè)定捕捉長(zhǎng)度; ③ 按F4鍵窗口縮小0.7倍; ④ 按F5鍵窗口放大1.4倍; ⑤ 按ESC鍵、回車(chē)鍵、鼠標(biāo)右鍵均可結(jié)束操作,退出程序; ⑥ 選取下一點(diǎn),移動(dòng)十字光標(biāo)鍵,此時(shí)在屏幕的最上面的一行的坐標(biāo)提示欄準(zhǔn)確地顯示出按用戶(hù)設(shè)定的捕捉角度和長(zhǎng)度所取得的落點(diǎn)相對(duì)于基準(zhǔn)點(diǎn)的偏移角度和長(zhǎng)度,滑動(dòng)十字光標(biāo)鍵直至用戶(hù)尋找到所需要的下一點(diǎn)并按下鼠標(biāo)左鍵,命令行重又出現(xiàn)上面的提示行,并進(jìn)行下一輪循環(huán); ⑦ 另外,用戶(hù)還可以點(diǎn)取View菜單下的Zoom菜單中的Zoom Window 、Zoom Previous、Zoom All等三個(gè)子項(xiàng)實(shí)現(xiàn)窗口放縮和Pan菜單實(shí)現(xiàn)屏幕漫游; 對(duì)于其他操作,用戶(hù)均可按屏幕命令行的中文提示方便地進(jìn)行操作。在非漢化AutoCAD 中運(yùn)行本程序時(shí),只需將程序中有關(guān)的中文提示行改成英文提示即可。 另外,由于不同的機(jī)型在AutoCAD環(huán)境下鍵盤(pán)返回碼可能稍有區(qū)別,所以要求用戶(hù)在應(yīng)用本程序之前對(duì)自己的機(jī)器鍵盤(pán)返回碼按如下方法作一次核實(shí): 在AutoCAD命令狀態(tài)下輸入(grread)并回車(chē),用戶(hù)此時(shí)可按下F2或F3、F4、F5鍵: 第一步:Command:(grread)回車(chē) 第二步:按下F2鍵 此時(shí),屏幕上回顯剛輸入的鍵值,比如對(duì)筆者使用的機(jī)器(AST PIII+4/66D)回顯為:(2 1 36)。 其具體涵義為:第一個(gè)數(shù)字"2"表示剛才是鍵盤(pán)輸入;第二個(gè)數(shù)字"136"表示本機(jī)器的"F2"鍵的返回碼。 按上述步驟依次對(duì)FF4、F5鍵的返回碼進(jìn)行核實(shí),筆者的機(jī)器該三鍵的返回碼分別為137、138、139。 如果核實(shí)結(jié)果與上述結(jié)果不符(比如,對(duì)某些機(jī)型,上述四鍵的返回碼分別為138、139、140、141),則應(yīng)對(duì)程序中的相應(yīng)語(yǔ)句作如下修改。 在"接受用戶(hù)輸入控制子程序"pull()中的鍵盤(pán)輸入部分的下述語(yǔ)句作對(duì)應(yīng)修改: (cond ((=c1 136)(ant));F2--此處136改為用戶(hù)的F2鍵返回碼 ((=c1 137)(leng); F3--此處137改為用戶(hù)的F3鍵返回碼 ((=c1 138); F4--此處138改為用戶(hù)的F4鍵返回碼 ((=c1 139); F5--此處139改為用戶(hù)的F5鍵返回碼 最后,需要指出的是:用戶(hù)自己的菜單文件ACAD.MNU可能增刪過(guò)菜單項(xiàng)或AutoCAD R13中,會(huì)使Zoom Window、Zoom All、Zoom Previous、Pan在菜單中位置發(fā)生改變。這樣,要求用戶(hù)在應(yīng)用本程序之前對(duì)自己的菜單項(xiàng)回碼按如下方法作一次核實(shí): 在AutoCAD命令狀態(tài)下輸入(grread)并回車(chē),用戶(hù)此時(shí)可點(diǎn)取下拉菜單View下的Zoom子菜單中的Window項(xiàng),對(duì)于筆者的菜單其返回值為:(4 6005)。其具體涵義為:第一個(gè)數(shù)字"4"表示剛才是下拉菜單輸入;第二個(gè)數(shù)字"6005"表示本菜單的Zoom Window菜單項(xiàng)的返回碼。用戶(hù)可按同樣的方法找到菜單項(xiàng)Zoom All、Zoom Previous、Pan的返回碼。并相應(yīng)地改變"接受用戶(hù)輸入控制子程序"pull()中的"點(diǎn)取下拉菜單"部分的下述語(yǔ)句作對(duì)應(yīng)修改: (cond ((=c1 6005)--此處6005改為用戶(hù)的Zoom Window菜單項(xiàng)返回碼; ((=c1 6007)--此處6007改為用戶(hù)的Zoom Previous菜單項(xiàng)返回碼; ((=c1 6008)--此處6008改為用戶(hù)的Zoom All菜單項(xiàng)返回碼; ((=c1 6011)--此外6011改為用戶(hù)的Pan菜單項(xiàng)返回碼; 五、結(jié)語(yǔ) 應(yīng)用本程序,可在制圖過(guò)程中很方便地實(shí)現(xiàn)某些特定角度和長(zhǎng)度的捕捉,簡(jiǎn)化了操作步驟和擊鍵次數(shù),根據(jù)目前的使用情況來(lái)看,畫(huà)線時(shí)可提高作圖速度4倍以上。至于AutoCAD內(nèi)部提供的正交和網(wǎng)點(diǎn)捕捉只是本程序當(dāng)捕捉角度為 90°時(shí)的一個(gè)特例。 將本程序的畫(huà)線子模塊 draw()中語(yǔ)句行 (command"line" pstart pend "") |
民眾工作室.制作 版權(quán)所有 |