找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 3293|回复: 22

[每日一码] 双向偏移--while用法

[复制链接]

已领礼包: 828个

财富等级: 财运亨通

发表于 2016-10-13 22:11:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 ngc 于 2016-10-13 22:18 编辑

看了好多关于while运用的帖子,也看了好多别人写的代码,我理解,就是有东西给while,他就会一直循环下去,没有就结束了。
下面是连续单选双向偏移的源码,带偏移后的改变线的颜色,或者改变线的图层,
  1. (defun c:tt()
  2.   (vl-load-com)
  3.   (princ "\n单选双向偏移")
  4.   (setq os (getvar 'osmode))
  5.   (setq cmd (getvar 'cmdecho))
  6.   (mapcar 'setvar (list 'osmode 'cmdecho) '(0 0))
  7.   (setq w (getreal "\n【偏移宽度】:"))
  8.   (while (setq enpline (car(entsel)))
  9.          (setvar 'osmode 0)
  10.          (vla-Offset (vlax-ename->vla-object enpline) (/ w 2.0))
  11.          (setq pline1 (entlast))
  12.          (command "change" pline1  "" "p" "c" "2" "" )
  13.          (vla-Offset (vlax-ename->vla-object enpline) (/ w -2.0))
  14.          (setq pline2 (entlast))
  15.          (command "change" pline2  "" "p" "la" "ngc6"  "" )
  16.    )
  17. (mapcar 'setvar (list 'osmode 'cmdecho) (list os cmd))
  18. (princ)
  19. )


单选双向偏移.gif

下面请教高手,怎么能够在没有pline线的情况下,边画边偏移,连续生成双线,
下面是图片说明:
连续画线偏移.gif


评分

参与人数 1D豆 +5 贡献 +1 收起 理由
newer + 5 + 1 很给力!经验;技术要点;资料分享奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 40个

财富等级: 招财进宝

发表于 2016-10-13 23:22:28 | 显示全部楼层
这样还能好点,不用就不执行。
(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)
)

评分

参与人数 1D豆 +1 收起 理由
ngc + 1 技术引导讨论和指点奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 1 反对 0

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2016-10-13 23:20:17 | 显示全部楼层
修改了下你的代码,这样能好点, 偏移距离那加个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)
)
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 1 反对 0

使用道具 举报

已领礼包: 5589个

财富等级: 富甲天下

发表于 2016-10-13 22:47:20 | 显示全部楼层
...
(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)
...

评分

参与人数 2D豆 +6 收起 理由
ngc + 1 技术引导讨论和指点奖!
newer + 5 及时回复奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2016-10-13 23:13:10 | 显示全部楼层
理解的对,挺通俗的。 表求值不为NIL,就一直循环。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2016-10-13 23:14:53 | 显示全部楼层
LISP没有

  1. do
  2. ...
  3. while (....)
复制代码

语句,这个就是为真就结束循环了。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 828个

财富等级: 财运亨通

 楼主| 发表于 2016-10-13 23:20:37 | 显示全部楼层

谢谢,我查了系统变量说明:
CMDACTIVE 系统变量

类型 整数
保存位置 尚未保存
初始值

指示激活的是普通命令、透明命令、脚本还是对话框。 系统将使用下列位码值之和将该设置存储为一个位码:
1
激活普通命令

2
激活普通命令和透明命令

4
激活脚本

8
激活对话框

16
激活 DDE

32
激活 AutoLISP(仅对 ObjectARX定义的命令可见)

64
激活 ObjectARX 命令


这个运用方法,不知道是什么意思?

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 828个

财富等级: 财运亨通

 楼主| 发表于 2016-10-13 23:30:29 | 显示全部楼层
根据HLCAD的方法,我改了改,还是不能实现,就是画一条多义线,就偏移,然后再画一条,再偏移,
最后右击鼠标退出程序,不用 (setq enpline (car(entsel))),直接画pline线就行
  1. (defun c:tt ()
  2.   (setq os (getvar 'osmode))
  3.   (setq cmd (getvar 'cmdecho))
  4.   (mapcar 'setvar (list 'osmode 'cmdecho) '(0 0))
  5.    (setq w 4)
  6.    (setq L-en (entlast));先设置最后一次的图元为L-en
  7.    (while (or (setq enpline (car(entsel)))
  8.               (progn (command "_.pline")
  9.                    (while (>(getvar 'cmdactive)0)(command pause))
  10.                    (setq enpline (entnext L-en))
  11.               );end progn
  12.           );end or

  13.    (setvar 'osmode 0)
  14.    (setq enpline (entlast))
  15.    (if (not (equal L-en enpline));比较 L-en enpline 是否相同,not nil为真 T
  16.      (progn
  17.        (vla-Offset (vlax-ename->vla-object enpline) (/ w 2.0))
  18.        (setq pline1 (entlast))
  19.        (vla-Offset (vlax-ename->vla-object enpline) (/ w -2.0))
  20.        (setq pline2 (entlast))
  21.        (setq ssbj (ssadd pline1))
  22.        (ssadd pline2 ssbj)
  23.       )
  24.     );end if
  25. );end while

  26.   (mapcar 'setvar (list 'osmode 'cmdecho) (list os cmd))
  27.    (princ)
  28.   )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2016-10-13 23:31:42 | 显示全部楼层

就是在命令激活状态下,比如画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 "")
)



表示当前命令我交互的完了,剩下的,只要命令还在执行,我就一直“回车”。直到命令结束。

评分

参与人数 1D豆 +1 收起 理由
ngc + 1 很给力!经验;技术要点;资料分享奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 828个

财富等级: 财运亨通

 楼主| 发表于 2016-10-13 23:39:10 | 显示全部楼层

看来还是要多看看前辈们的代码,多理解,有些地方确实不知道怎么用
请问,能否实现画一条多义线,就偏移,然后再画一条,再偏移,最后右击鼠标退出程序
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2016-10-13 23:42:50 | 显示全部楼层

你想要 画一段线 就偏移,然后接着PLINE,用命令不行的,命令执行内部,只能接受命令需要的参数,你给的每个值都对应命令要求的参数。

你可以写自己的PLINE啊,线都不用先画出来,你用GETPOINT不断的取点,然后画临时的向量到屏幕,中间把点都保存到表里面,最后结束的时候,根据点表再生成PLINE。

点评

ngc
好主意,我试试  发表于 2016-10-13 23:47
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2016-10-14 00:02:53 | 显示全部楼层

下面代码是一个结构,绘制单线的,你可以在里面加进去偏移的代码。

(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)
)

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 8734个

财富等级: 富甲天下

发表于 2016-10-14 00:07:24 | 显示全部楼层
啥也不说了,感谢楼主分享哇!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 828个

财富等级: 财运亨通

 楼主| 发表于 2016-10-14 00:42:16 | 显示全部楼层

非常感谢版主,你给的代码,我已经理解了,并加了标注,有很多值得学习的地方

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 828个

财富等级: 财运亨通

 楼主| 发表于 2016-10-14 00:44:40 | 显示全部楼层
  1. (defun c:tt (/ p1 pt pts)
  2.   (setq i 0)
  3.   (setvar "plinewid" 0);多段线宽度
  4.   ;顺序说明:
  5.   
  6.   ;第一个假如等于零,执行:(setq pt (getpoint "\n第一点<退出>:"))
  7. ;;;                          (setq i 1
  8. ;;;                                p1 pt
  9. ;;;                                pts (cons pt pts)
  10. ;;;                           )
  11.   
  12.   ;第一个假如不等于零,执行:(setq pt (getpoint p1 "\n下一点<结束>:"))
  13. ;;;  点数超零时触发第二个假如(if (> (length pts) 0)
  14. ;;;                                   (grdraw p1 pt 1)
  15. ;;;;;;                            )
  16. ;;;                          (setq i 1
  17. ;;;                                p1 pt
  18. ;;;                                pts (cons pt pts);向表的头部添加一个元素,或构造一个点对
  19.   (while
  20.     ;第一个假如
  21.        (if (= i 0)
  22.            (setq pt (getpoint "\n第一点<退出>:"));等于零,执行
  23.            (setq pt (getpoint p1 "\n下一点<结束>:"));不等于零,临时画红线
  24.        );end 第一个if
  25.     ;第二个假如
  26.        (if (> (length pts) 0);以整数形式返回表中元素的数目
  27.              (grdraw p1 pt 1);在当前视口中的两个点之间显示一条矢量线(grdraw from to color [highlight])
  28.        );end 第二个if
  29.    
  30.     (setq i 1
  31.           p1 pt
  32.           pts (cons pt pts);向表的头部添加一个元素,后面的点往前添加,所以下面需要反转点表
  33.     )
  34.   );end while
  35.   (redraw);重画当前视口
  36.   (setq pts (reverse pts);将表的元素顺序倒置后返回
  37.   i 0)
  38.   (command "pline")
  39.   (while (/= 0 (getvar "cmdactive"))
  40.      (command (nth i pts));起点
  41.      (setq i (1+ i));第二点,直到终点
  42.   );end while
  43.   (princ)
  44. )
版主的代码,我加了标注,
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-5-13 05:22 , Processed in 0.286245 second(s), 61 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表