双向偏移--while用法
本帖最后由 ngc 于 2016-10-13 22:18 编辑看了好多关于while运用的帖子,也看了好多别人写的代码,我理解,就是有东西给while,他就会一直循环下去,没有就结束了。
下面是连续单选双向偏移的源码,带偏移后的改变线的颜色,或者改变线的图层,
(defun c:tt()
(vl-load-com)
(princ "\n单选双向偏移")
(setq os (getvar 'osmode))
(setq cmd (getvar 'cmdecho))
(mapcar 'setvar (list 'osmode 'cmdecho) '(0 0))
(setq w (getreal "\n【偏移宽度】:"))
(while (setq enpline (car(entsel)))
(setvar 'osmode 0)
(vla-Offset (vlax-ename->vla-object enpline) (/ w 2.0))
(setq pline1 (entlast))
(command "change" pline1"" "p" "c" "2" "" )
(vla-Offset (vlax-ename->vla-object enpline) (/ w -2.0))
(setq pline2 (entlast))
(command "change" pline2"" "p" "la" "ngc6""" )
)
(mapcar 'setvar (list 'osmode 'cmdecho) (list os cmd))
(princ)
)
下面请教高手,怎么能够在没有pline线的情况下,边画边偏移,连续生成双线,
下面是图片说明:
这样还能好点,不用就不执行。
(defun c:tt ()
(vl-load-com)
(princ "\n单选双向偏移")
(if (setq w (getreal "\n【偏移宽度】<退出>:"))
(progn
(setq os (getvar 'osmode))
(setq cmd (getvar 'cmdecho))
(mapcar
'setvar
(list 'osmode 'cmdecho)
'(0 0)
)
(while (setq enpline (car (entsel)))
(setvar 'osmode 0)
(vla-Offset (vlax-ename->vla-object enpline) (/ w 2.0))
(setq pline1 (entlast))
(command "change" pline1 "" "p" "c" "2" "")
(vla-Offset (vlax-ename->vla-object enpline) (/ w -2.0))
(setq pline2 (entlast))
(command "change" pline2 "" "p" "la" "ngc6" "")
)
(mapcar
'setvar
(list 'osmode 'cmdecho)
(list os cmd)
)
)
)
(princ)
)
修改了下你的代码,这样能好点, 偏移距离那加个IF,输入回车就不执行循环了,否则代码就出错了。
(defun c:tt ()
(vl-load-com)
(princ "\n单选双向偏移")
(setq os (getvar 'osmode))
(setq cmd (getvar 'cmdecho))
(mapcar
'setvar
(list 'osmode 'cmdecho)
'(0 0)
)
(if (setq w (getreal "\n【偏移宽度】<退出>:"))
(while (setq enpline (car (entsel)))
(setvar 'osmode 0)
(vla-Offset (vlax-ename->vla-object enpline) (/ w 2.0))
(setq pline1 (entlast))
(command "change" pline1 "" "p" "c" "2" "")
(vla-Offset (vlax-ename->vla-object enpline) (/ w -2.0))
(setq pline2 (entlast))
(command "change" pline2 "" "p" "la" "ngc6" "")
)
)
(mapcar
'setvar
(list 'osmode 'cmdecho)
(list os cmd)
)
(princ)
)
...
(setq w (getreal "\n【偏移宽度】:"))
(setq L-en (entlast))
(while (or (setq enpline (car(entsel)))
(progn (command "_.pline")
(while (>(getvar 'cmdactive)0)(command pause))
(setq enpline (entnext L-en))
)
)
(setvar 'osmode 0)
... 理解的对,挺通俗的。 表求值不为NIL,就一直循环。
LISP没有
do
...
while (....)
语句,这个就是为真就结束循环了。 HLCAD 发表于 2016-10-13 22:47
谢谢,我查了系统变量说明:
CMDACTIVE 系统变量
类型 整数
保存位置 尚未保存
初始值 无
指示激活的是普通命令、透明命令、脚本还是对话框。 系统将使用下列位码值之和将该设置存储为一个位码:
1激活普通命令
2激活普通命令和透明命令
4激活脚本
8激活对话框
16激活 DDE
32激活 AutoLISP(仅对 ObjectARX定义的命令可见)
64激活 ObjectARX 命令
这个运用方法,不知道是什么意思?
根据HLCAD的方法,我改了改,还是不能实现,就是画一条多义线,就偏移,然后再画一条,再偏移,
最后右击鼠标退出程序,不用 (setq enpline (car(entsel))),直接画pline线就行
(defun c:tt ()
(setq os (getvar 'osmode))
(setq cmd (getvar 'cmdecho))
(mapcar 'setvar (list 'osmode 'cmdecho) '(0 0))
(setq w 4)
(setq L-en (entlast));先设置最后一次的图元为L-en
(while (or (setq enpline (car(entsel)))
(progn (command "_.pline")
(while (>(getvar 'cmdactive)0)(command pause))
(setq enpline (entnext L-en))
);end progn
);end or
(setvar 'osmode 0)
(setq enpline (entlast))
(if (not (equal L-en enpline));比较 L-en enpline 是否相同,not nil为真 T
(progn
(vla-Offset (vlax-ename->vla-object enpline) (/ w 2.0))
(setq pline1 (entlast))
(vla-Offset (vlax-ename->vla-object enpline) (/ w -2.0))
(setq pline2 (entlast))
(setq ssbj (ssadd pline1))
(ssadd pline2 ssbj)
)
);end if
);end while
(mapcar 'setvar (list 'osmode 'cmdecho) (list os cmd))
(princ)
) ngc 发表于 2016-10-13 23:20
就是在命令激活状态下,比如画PLINE,命令中间查询这个系统变量cmdactive就不等于0了。
用途挺广泛的,比如命令的参数需要你交互,不能在命令里面给出来,也不知道需要多少个参数的时候,
比如画PLINE
(defun c:tt ()
(command ".pline")
(while (/= (getvar "cmdactive") 0)
(command ".pause")
)
(princ)
)
这个代码,如果不用这个系统变量,很不好利用PLINE命令的。
还比如,有些命令,比如STYLE等等,很多时候需要一直按“Y”,但不同的命令需要的"Y”不一样多,也可以利用这个性质
(while (/= (getvar "cmdactive") 0)
(command "Y")
)
意思就是只要当前命令还要激活,我就一直输入“Y”。
还有:
(while (/= (getvar "cmdactive") 0)
(command "")
)
表示当前命令我交互的完了,剩下的,只要命令还在执行,我就一直“回车”。直到命令结束。
newer 发表于 2016-10-13 23:31
看来还是要多看看前辈们的代码,多理解,有些地方确实不知道怎么用
请问,能否实现画一条多义线,就偏移,然后再画一条,再偏移,最后右击鼠标退出程序
ngc 发表于 2016-10-13 23:30
你想要 画一段线 就偏移,然后接着PLINE,用命令不行的,命令执行内部,只能接受命令需要的参数,你给的每个值都对应命令要求的参数。
你可以写自己的PLINE啊,线都不用先画出来,你用GETPOINT不断的取点,然后画临时的向量到屏幕,中间把点都保存到表里面,最后结束的时候,根据点表再生成PLINE。
ngc 发表于 2016-10-13 23:39
下面代码是一个结构,绘制单线的,你可以在里面加进去偏移的代码。
(defun c:tt (/ p1 pt pts)
(setq i 0)
(setvar "plinewid" 0)
(while (if (= i 0)
(setq pt (getpoint "\n第一点<退出>:"))
(setq pt (getpoint p1 "\n下一点<结束>:"))
)
(if (> (length pts) 0)
(grdraw p1 pt 1)
)
(setq i 1
p1 pt
pts (cons pt pts)
)
)
(redraw)
(setq pts (reverse pts) i 0)
(command "pline")
(while (/= 0 (getvar "cmdactive"))
(command (nth i pts))
(setq i (1+ i))
)
(princ)
)
啥也不说了,感谢楼主分享哇! newer 发表于 2016-10-14 00:02
非常感谢版主,你给的代码,我已经理解了,并加了标注,有很多值得学习的地方
(defun c:tt (/ p1 pt pts)
(setq i 0)
(setvar "plinewid" 0);多段线宽度
;顺序说明:
;第一个假如等于零,执行:(setq pt (getpoint "\n第一点<退出>:"))
;;; (setq i 1
;;; p1 pt
;;; pts (cons pt pts)
;;; )
;第一个假如不等于零,执行:(setq pt (getpoint p1 "\n下一点<结束>:"))
;;;点数超零时触发第二个假如(if (> (length pts) 0)
;;; (grdraw p1 pt 1)
;;;;;; )
;;; (setq i 1
;;; p1 pt
;;; pts (cons pt pts);向表的头部添加一个元素,或构造一个点对
(while
;第一个假如
(if (= i 0)
(setq pt (getpoint "\n第一点<退出>:"));等于零,执行
(setq pt (getpoint p1 "\n下一点<结束>:"));不等于零,临时画红线
);end 第一个if
;第二个假如
(if (> (length pts) 0);以整数形式返回表中元素的数目
(grdraw p1 pt 1);在当前视口中的两个点之间显示一条矢量线(grdraw from to color )
);end 第二个if
(setq i 1
p1 pt
pts (cons pt pts);向表的头部添加一个元素,后面的点往前添加,所以下面需要反转点表
)
);end while
(redraw);重画当前视口
(setq pts (reverse pts);将表的元素顺序倒置后返回
i 0)
(command "pline")
(while (/= 0 (getvar "cmdactive"))
(command (nth i pts));起点
(setq i (1+ i));第二点,直到终点
);end while
(princ)
)版主的代码,我加了标注,
页:
[1]
2