快精灵印艺坊 您身边的文印专家
广州名片 深圳名片 会员卡 贵宾卡 印刷 设计教程
产品展示 在线订购 会员中心 产品模板 设计指南 在线编辑
 首页 名片设计   CorelDRAW   Illustrator   AuotoCAD   Painter   其他软件   Photoshop   Fireworks   Flash  

 » 彩色名片
 » PVC卡
 » 彩色磁性卡
 » 彩页/画册
 » 个性印务
 » 彩色不干胶
 » 明信片
   » 明信片
   » 彩色书签
   » 门挂
 » 其他产品与服务
   » 创业锦囊
   » 办公用品
     » 信封、信纸
     » 便签纸、斜面纸砖
     » 无碳复印纸
   » 海报
   » 大篇幅印刷
     » KT板
     » 海报
     » 横幅

AutoCAD中特定角度及长度捕获的实现方式

    一、引言在AutoCAD中的角度捕获只有当正交状态打开时的直和水平方向,对于其他特别角度无能为力;另外,其网点捕获也是相对于X轴和Y轴,无法实现其他方向的特别长度捕获,给绘图带来极大的不方便。

    在应用 AutoCAD 进行设计制图的操作中, LINE 和POLYLINE 是使用频率最高的两个命令, 常常要碰到在某些特定角度上绘制特定长度的简朴线或复合线的情况,因而实现这两个捕获对提高AutoCAD 作图效率很有实用价值。

    二、方式原理

    所谓角度捕获,是指当十字光标在某一角度α的一定范围内选取一点时,该点自动落在该α角度线上;当我们设定捕获角度为α时,将会以基准点作为原点、自X轴正方向出发,将整个屏幕划分为[360/α]个区间,则NXα角度就是角度捕获线,其中,0≤N≤[360/α],[360/α]表示不大于360/α的整数。

    所谓长度捕获,是在角度捕获的基础上,在某一角度线上有一系列捕获点,该系列点离基准点的距离为捕获长度的正整数倍,当选取直线上的一点时,落点自动落到离其最近的捕获点上。

    实现特定角度和长度捕获的要害点是:当十字光标(即十字交叉线)移动时,程序要随时跟踪其交叉点的位置,并将该位置与用户所设定的捕获角度与长度对应起来,从而计算出在该角度上的落点。

    以下举例说明该两个捕获的实现过程:

    假定捕获角度为α=30°,捕获长度为L.

    当十字光标在任意的某一区间内移动时,比如在第5区间(120°~150 °)内移动时,此时,落点只能在120°或150°线上(该线在图中并不直接显示),该两根角度线的中央线为135°。当十字光标的中央点处在120°~135°之间时, 则落点应在120°线上,该落点的详细位置为由十字光标的中央点向120°线作垂线来获得,其交点D(称为垂点)即为落点,为直观起见,此时由基准点(此处为O点)向落点作一橡筋拖曳线,该橡筋拖曳线随十字光标的移动而相应移动,显示出拖动过程(见图1);同样,当十字光标的中央点处在135°~150°之间时,则落点应在150°线上,并显示相应的橡筋拖曳线。该橡筋拖曳线并不是真正的线段, 只是用XOR墨水绘制的一个向量,当用XOR墨水重新绘制一遍该向量时,该向量将从屏幕上消失,这就是本程序实现光标拖动的原理。

    落点落在某一捕获角度线上时,还得落在捕获长度L 的整数倍的点(称为捕获点)上,还是针对图1,其垂点必然处于某两个捕获点A与B之间,设A与B的中点为C,当D处于A与C之间时,落点应为A;当D处于C与B之间时,落点应为B (见图1)。其中:

    ―― ――

    OA = n XL ; OB = (n + 1) XL

    n: 非负整数。

    L: 捕获长度。 此时,程序通过一定的操作将在屏幕的最上面的坐标提示行正确地显示落点相对基准点的偏移长度和偏移角度。用户可以滑动鼠标正确捕获到目标点。

    至此,已实现某些特定角度及长度的捕获。为了满意在程序执行过程中能随时更改捕获角度和捕获长度的需要,本程序还增加了相应的模块;另外,本程序中嵌入了窗口放缩功能模块,通过点取下拉菜单中窗口及漫游子菜单,方便了各种作图的需要。

    三、源程序清单

    ;; OS.LSP源程序

    ;;err(),出错处理子程序

    (defun err ( msg)

    (if (/= msg "Function cancelled")

    (princ(strcat "nError:" msg)) ;打印错误内容

    ) ;for if

    (setq *error* olderr)

    (setvar "cmdecho" scmd)

    (setvar "osmode" cosmode)

    (setvar "coords" ccoords)

    (princ "nnt ――多谢使用角度捕获2.0版,程序非正常结束――!n")

    (princ)

    ) ;for defun err

    ;; ant(),设定捕获角度子程序

    (defun ant ( / ang0 ang1 )

    (setq ang0 (* an0 (/ 180 pi)) )

    (princ (strcat "n请输入捕获角度:<" (rtos ang0) ">_"))

    (INITGET 4)

    (setq ang1 (getreal))

    (if (not (null ang1))

    (setq an0 (* ang1 (/ pi 180)))

    )

    (princ "n F2/F3/F4/F5/ESC/Return /下一点:")

    ) ;for defun ant

    ;; leng(),设定捕获长度距离子程序

    (defun leng ( / leng0 leng1 )

    (setq leng0 len0)

    (princ (strcat "n 请输入捕获长度距离:<" (rtos leng0) ">_"))

    (INITGET 4)

    (setq leng1 (getreal))

    (if (not (null leng1))

    (setq len0 leng1 )

    )

    (princ "n F2/F3/F4/F5/ESC/Return /下一点:")

    ) ;for defun lent

    ;; field(),判定十字光标所在区间,并投影到相应的捕获角度线上

    (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(), 十字光标投影到相应的捕获角度上后,以用户设定的长度

    ;; 捕获计算落点

    (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(), 对上一次显示的拖曳线进行"或"操作,使其从屏幕上消失,

    ;; 并绘制下一次拖曳线

    (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(), 在屏幕的最上一行的坐标栏显示长度和角度

    (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(), 对程序进行初始化

    (defun init ( / )

    (setq scmd (getvar "cmdecho"));保留原命令回显方法

    (setq ccoords (getvar "coords"));保留原坐标显示方法

    (setq cosmode (getvar "osmode"))

    (setq olderr *error* *error* err) ;出错处理

    (setvar "cmdecho" 0);不回显

    (setvar "coords" 0) ;不显示坐标

    (setvar "osmode" 0 ) ;取消捕获

    (setq b 0 b1 0 c \\'(0 0) )

    (setq pstart (getpoint "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 /下一点::")

    (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(), 设置退出程序的控制变量

    (defun home ( / )

    (setq b 3)

    (setq b1 1)

    ) ;for defun home

    ;; pull(), 接受用户输入控制子程序

    (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) );只移动十字光标时

    (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);用鼠标在屏幕上点取一点时

    (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);键盘输入

    (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 /下一点:")

    );for progn

    );for (cond (= b 2))

    ((= b 4);点取下拉菜单时

    (progn

    (setq c1 (cadr a))

    (princ "n")

    (cond ((= c1 6005)

    (progn

    (command"zoom" "w")

    (princ "n 第一角点:")

    (command pause)

    (princ "n 第二角点:")

    (command pause)

    )

    ) ;for (= c1 6005)

    ((= c1 6007)

    (command"zoom" "p" ))

    ((= c1 6008)

    (command"zoom" "a" ))

    ((= c1 6011)

    (progn

    (command"pan")

    (princ "n 第一参考点:")

    (command pause)

    (princ "n 第二参考点:")

    command pause)

    )

    ) ;for (= c1 6011)

    ;;else

    (T (princ "n 未定义的菜单"))

    ) ;for cond

    (princ "n F2/F3/F4/F5/ESC/Return /下一点:")

    ) ;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 /下一点:")

    (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 "nnt ――角度捕获2.0版――n")

    (princ "nnt**宁波大学建筑设计研究院――程建华,1996**n")

    (princ)

    ) ;for defun os

    四、程序的安装与使用

    1. 程序的安装

    以下三种装载方法,用户任选一种即可: 在AutoCAD环境下,将OS.LSP拷至当前目录,再执行(LOAD"OS")即可装载OS.LSP.也可先将OS.LSP拷至ACADSUPPORT子目录下,再在ACADSUPPORTACADR12.LSP或ACADR13.LSP中加入下面一句语句实现启动AutoCAD时自动装载:

    (AUTOLOAD "OS" \\'("OS"))

    也可将OS.LSP拷至ACADSUPPORT子目录下,在ACADSUPPORT\子目录下的菜单文件ACAD.MNU中的合适位置加上下面的一句语句,即可直接在菜单中点取角度捕获操作:

    。

    。

    。

    [角度捕获]^c^c(load"c:/acad/support/os.lsp") os

    。

    。

    。

    2. 程序的使用

    在一幅图中第一次使用该程序时,需要用户输入捕获角度和捕获长度,第二次调用本程序时,程序可自动采用上一次最后设定的捕获角度和长度作为默认值。然后,程序需要用户选择输入一点作为基准点,此时命令行提示:

    F2/F3/F4/F5/ESC/Return /下一点:

    用户根据该提示可任选其中的一种操作,详细解释如下:

    ① 按F2键重新设定捕获角度;

    ② 按F3键重新设定捕获长度;

    ③ 按F4键窗口缩小0.7倍;

    ④ 按F5键窗口放大1.4倍;

    ⑤ 按ESC键、回车键、鼠标右键均可结束操作,退出程序;

    ⑥ 选取下一点,移动十字光标键,此时在屏幕的最上面的一行的坐标提示栏正确地显示出按用户设定的捕获角度和长度所取得的落点相对于基准点的偏移角度和长度,滑动十字光标键直至用户寻找到所需要的下一点并按下鼠标左键,命令行重又出现上面的提示行,并进行下一轮循环;

    ⑦ 另外,用户还可以点取View菜单下的Zoom菜单中的Zoom Window 、Zoom Previous、Zoom All等三个子项实现窗口放缩和Pan菜单实现屏幕漫游; 对于其他操作,用户均可按屏幕命令行的中文提示方便地进行操作。在非汉化AutoCAD 中运行本程序时,只需将程序中有关的中文提示行改成英文提示即可。 另外,由于不同的机型在AutoCAD环境下键盘返回码可能稍有区别,所以要求用户在应用本程序之前对自己的机器键盘返回码按如下方式作一次核实:

    在AutoCAD命令状态下输入(grread)并回车,用户此时可按下F2或F3、F4、F5键:

    第一步:Command:(grread)回车

    第二步:按下F2键

    此时,屏幕上回显刚输入的键值,比如对笔者使用的机器(AST PIII+4/66D)回显为:(2 1 36)。

    其详细涵义为:第一个数字"2"表示刚才是键盘输入;第二个数字"136"表示本机器的"F2"键的返回码。

    按上述步骤依次对FF4、F5键的返回码进行核实,笔者的机器该三键的返回码分别为137、138、139.

    假如核实结果与上述结果不符(比如,对某些机型,上述四键的返回码分别为138、139、140、141),则应对程序中的相应语句作如下修改。

    在"接受用户输入控制子程序"pull()中的键盘输入部分的下述语句作对应修改:

    (cond ((=c1 136)(ant));F2――此处136改为用户的F2键返回码

    ((=c1 137)(leng);

    F3――此处137改为用户的F3键返回码

    ((=c1 138);

    F4――此处138改为用户的F4键返回码

    ((=c1 139);

    F5――此处139改为用户的F5键返回码

    最后,需要指出的是:用户自己的菜单文件ACAD.MNU可能增删过菜单项或AutoCAD R13中,会使Zoom Window、Zoom All、Zoom Previous、Pan在菜单中位置发生改变。这样,要求用户在应用本程序之前对自己的菜单项回码按如下方式作一次核实:

    在AutoCAD命令状态下输入(grread)并回车,用户此时可点取下拉菜单View下的Zoom子菜单中的Window项,对于笔者的菜单其返回值为:(4 6005)。其详细涵义为:第一个数字"4"表示刚才是下拉菜单输入;第二个数字"6005"表示本菜单的Zoom Window菜单项的返回码。用户可按同样的方式找到菜单项Zoom All、Zoom Previous、Pan的返回码。并相应地改变"接受用户输入控制子程序"pull()中的"点取下拉菜单"部分的下述语句作对应修改:

    (cond ((=c1 6005)――此处6005改为用户的Zoom Window菜单项返回码;

    ((=c1 6007)――此处6007改为用户的Zoom Previous菜单项返回码;

    ((=c1 6008)――此处6008改为用户的Zoom All菜单项返回码;

    ((=c1 6011)――此外6011改为用户的Pan菜单项返回码;

    五、结语

    应用本程序,可在制图过程中很方便地实现某些特定角度和长度的捕获,简化了操作步骤和击键次数,根据目前的使用情况来看,画线时可提高作图速度4倍以上。至于AutoCAD内部提供的正交和网点捕获只是本程序当捕获角度为 90°时的一个特例。

    将本程序的画线子模块 draw()中语句行

    (command"line" pstart pend "")


返回类别: AuotoCAD教程
上一教程: AutoCAD中关于层的用法介绍
下一教程: AUTOLISP程序设计技巧

您可以阅读与"AutoCAD中特定角度及长度捕获的实现方式"相关的教程:
· 巧用AutoCAD帮助计算传动带的长度
· 在AutoCAD中实现“倾斜”功能
· 利用VBA编程实现从EXCEL表到AUTOCAD表转变
· 应用AutoCAD几何计算器实现迅速定位
· AutoCAD中对齐命令的实战运用
    微笑服务 优质保证 索取样品