找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 3479|回复: 13

[每日一码] 沿直线画圆环

[复制链接]
发表于 2013-6-3 13:11:38 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 hai20130408 于 2013-6-3 14:13 编辑

前面发了几篇工作中随手编的lisp程序,程序随便的以至于后来自己都觉得有班门弄斧之嫌,但各位高手的精彩点评,也让自己受益匪浅啊,其一些建议都是考虑到了程序的容错性,简要性。今天我接着抛一块臭泥砖,引各位金玉良言,欢迎各位拍砖。
  1. (setq rcircle 1);;;圆环半径
  2. (setq XX_jl 4);;;直线方向长度
  3. (defun ZX(rcircle XX_jl / acaddocument acadobject application msg mspace os rcircle varlst x xx_angle xx_endpoint
  4.                xx_object xx_pt xx_ptcircle xx_ptcirclef xx_ss xx_sscircle xx_startpoint)
  5. setq XX_pt (getpoint "\n输入点"))
  6. (while (not xx_pt)(setq XX_pt (getpoint "\n输入点")) )
  7.   (setq os (getvar "osmode"))
  8.    (setq varlst (mapcar (function (lambda (x) (list 'setvar x (getvar x))))
  9.                    '("autosnap" "osmode" "pickbox")));_定义还原变量
  10.    (setvar "osmode" 0)
  11.   (setq AcadObject (vlax-get-acad-object)
  12.         AcadDocument (vla-get-ActiveDocument AcadObject)
  13.   Application (vla-get-Application AcadDocument)
  14.   mspace (vla-get-ModelSpace AcadDocument)
  15.       )
  16.   (defun *error* (msg)
  17.       (mapcar 'eval varlst)
  18.       (if (not (member
  19.                 msg
  20.                 '(nil "函数被取消" ";错误:quit / exit abort")
  21.                )
  22.           )      
  23.       (princ (strcat ";错误:" msg))
  24.       )
  25.    )
  26.    (setq xx_ss (ssget XX_pt))
  27.    (setq xx_object (vlax-ename->vla-object (ssname xx_ss 0)))
  28.    (setq xx_startpoint (vlax-curve-getStartPoint xx_object))
  29.    (setq xx_endpoint (vlax-curve-getEndPoint xx_object))
  30. ;;;   (vla-zoomwindow Application (vlax-3d-point xx_startpoint) (vlax-3d-point xx_endpoint))
  31. ;;;   (command "_delay" 200)
  32.    (setq xx_ssdount (ssget))
  33.    (setq xx_ptcircle0 (vlax-safearray->list (vlax-variant-value(vlax-get-property (vlax-ename->vla-object (ssname xx_ssdount 0)) 'Coordinate 0))))
  34.    (setq xx_ptcircle1 (vlax-safearray->list (vlax-variant-value(vlax-get-property (vlax-ename->vla-object (ssname xx_ssdount 0)) 'Coordinate 1))))
  35.    (setq xx_ptcircle (list (/ (+ (car xx_ptcircle0) (car xx_ptcircle1)) 2.0) (/ (+ (cadr xx_ptcircle0) (cadr xx_ptcircle1)) 2.0) 0))
  36. ;;;   (setq xx_ptcircle (cdr (assoc 10 (entget (ssname xx_ssdount 0)))))
  37.    (setq XX_angle (angle xx_ptcircle XX_pt))
  38.    (setq xx_ptcirclef (polar xx_ptcircle XX_angle XX_jl))
  39. ;;;   (vl-cmdf "_circle" xx_ptcirclef rcircle "")
  40. ;;;   (vla-addcircle mSpace (vlax-3d-point xx_ptcirclef) rcircle)
  41.    (vl-cmdf "donut" 0 rcircle xx_ptcirclef "")
  42.    (princ "完成")
  43.    (*error* nil)
  44.    (setvar "osmode" os)
  45.    (prin1)
  46. )

  47. (defun c:tt()
  48.   (ZX rcircle XX_jl)
  49. )



6.gif

评分

参与人数 1D豆 +6 收起 理由
XDSoft + 6 好主题奖!

查看全部评分

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

已领礼包: 593个

财富等级: 财运亨通

发表于 2013-6-3 13:21:43 来自手机 | 显示全部楼层
1 看lz用了vla,想必对activex很熟悉,画圆环用vla方法更好
2 对变量的命名在alisp中还是简单明了,可读性更强,而且码那么多字又费时费力的
3 函数可以写成仅对单一曲线操作,圆环写另外一个函数(可以供别的程序用),这样写命令时就可以处理选择集

点评

是的, vl-cmdf容易出错; 命名确实养成了一个坏习惯,不过都是复制粘贴的,嘿嘿,慢慢改,但是因为有时为了调试方便,把所有局部变量都设置为全局变量了,但是又为了防止变量干涉。所以把每个变量都冠以该函数的  详情 回复 发表于 2013-6-3 13:33
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-6-3 13:33:42 | 显示全部楼层
eachy 发表于 2013-6-3 13:21
1 看lz用了vla,想必对activex很熟悉,画圆环用vla方法更好
2 对变量的命名在alisp中还是简单明了,可读性 ...

是的,
vl-cmdf容易出错;
命名确实养成了一个坏习惯,不过都是复制粘贴的,嘿嘿,慢慢改,但是因为有时为了调试方便,把所有局部变量都设置为全局变量了,但是又为了防止变量干涉。所以把每个变量都冠以该函数的函数名。都调试成功后,再改为局部变量;
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-6-3 14:00:55 | 显示全部楼层
本帖最后由 Lispboy 于 2013-6-3 14:02 编辑

楼主,这个地方:

  1. (setq XX_pt (getpoint "\n输入点"))


如果用户回车了,没选点尼,程序接下去运行就要错了,所以,还是建议你在程序中加上必要的判断语句,需要的条件都成立了,再运行下面的代码。
我的经验是,凡是用户和ACAD交互的地方,一定要判断返回值。

点评

呵呵,是的,我只图简单了,这点确实有待改进。可以改成:(setq XX_pt (getpoint "\n输入点"))(while (not xx_pt)(setq XX_pt (getpoint "\n输入点")) )  详情 回复 发表于 2013-6-3 14:05
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-6-3 14:05:07 | 显示全部楼层
Lispboy 发表于 2013-6-3 14:00
楼主,这个地方:

呵呵,是的,我只图简单了,这点确实有待改进。可以改成:(setq XX_pt (getpoint "\n输入点"))(while (not xx_pt)(setq XX_pt (getpoint "\n输入点")) )

点评

你是希望用户循环取点吗? 你那么写有些冗余了,可以这样: 提示字符里面明确告诉用户,回车结束。  详情 回复 发表于 2013-6-3 14:22
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-6-3 14:13:58 | 显示全部楼层
本帖最后由 Lispboy 于 2013-6-3 14:16 编辑

另外:

  1. (setq varlst (mapcar (function (lambda (x) (list 'setvar x (getvar x))))
  2.                    '("autosnap" "osmode" "pickbox")));_定义还原变量
  3.    (setvar "osmode" 0)

赞一句这个写法,看到你错误处理有还原,但是程序结束后,你用的是:

  1. (setvar "osmode" os)


建议你最后程序也执行下错误处理里面的还原变量。建议保存写个函数,恢复写个函数

如:
  1. (defun sav-var (varList)
  2.    (setq $global-sysVar-varlst (mapcar (function (lambda (x) (list 'setvar x (getvar x)))) varlist)
  3.    t
  4. )
  5. (defun res-var ()
  6.    (mapcar 'eval $global-sysVar-varlst)
  7.    t
  8. )


这样,在程序开始的时候用

  1. (sav-var  '("autosnap" "osmode" "pickbox"))


程序结束前执行

  1. (res-var)

点评

呵呵,是的,另外我的程序中的ssget没有选中实体,理论上也需要进行一个错误处理,这个我就不写了。  详情 回复 发表于 2013-6-3 14:17
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-6-3 14:17:11 | 显示全部楼层

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

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-6-3 14:20:09 | 显示全部楼层
类似于XDRX_API里面的BEGIN....END结构,在增强你的代码,begin里面,除了保存变量,你还可以把 UNDO信息保存起来,结束恢复变量的时候恢复UNDO标志。 这样,如果你程序执行过很多命令时候,用户一个UNDO就回到程序开始运行前。
  1. (begin .....)
  2. ......
  3. (end)

点评

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

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-6-3 14:22:37 | 显示全部楼层
hai20130408 发表于 2013-6-3 14:05
呵呵,是的,我只图简单了,这点确实有待改进。可以改成:(setq XX_pt (getpoint "\n输入点"))(while (no ...

你是希望用户循环取点吗? 你那么写有些冗余了,可以这样:

  1. (while (setq pt (getpoint "\n拾取点<退出>:"))
  2.     ......
  3. )


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

使用道具 举报

 楼主| 发表于 2013-6-3 14:31:09 | 显示全部楼层
Lispboy 发表于 2013-6-3 14:20
类似于XDRX_API里面的BEGIN....END结构,在增强你的代码,begin里面,除了保存变量,你还可以把 UNDO信息保 ...

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

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2013-6-3 16:00:18 | 显示全部楼层
[pcode=lisp,true];;绘制圆环,这个经常用,写个函数
;;参数:中心点、半径、宽度
;;      这里参数给个 space 适用多数情况 Modelspace
;;      Paperspace Blockdeference ..
(defun Ea:AddDount (space p r w)
  (setq  p1 (polar p 0. (* r 0.5))
  p2 (polar p1 pi r) ;_圆环直径上的两个端点
  )
  (setq  pl
   (vla-addlightweightpolyline
     space
     (vlax-make-variant
       (vlax-safearray-fill
         (vlax-make-safearray vlax-vbdouble '(0 . 3)) ;_ 这里只构造两个点,后面用 Closed 属性
         (apply
     'append
     (mapcar '(lambda (x) (list (car x) (cadr x))) (list p1 p2));_这里用的逆时针
         ) ;_ 3D -> 2D point
       )
     )
   )
  )
  ;;设定Bulge, 对半圆来说 = 1 和 -1
  (vla-setbulge pl 0 -1.0);_如果顺时针绘制Bulge=1.0
  (vla-setbulge pl 1 -1.0)
  (vla-put-closed pl :vlax-true) ;_闭合Pline
  (vla-put-ConstantWidth pl (* w 0.5)) ;_据说乘法比除法快一点点
)
;;开始主程序
(defun c:tt (/ ss sp p1 pt)
  ;;这里演示在模型空间操作,仅用到 Modelspace, ms 简写
  (setq  ms (vla-get-modelspace
       (vla-get-activedocument (vlax-get-acad-object))
     )
  )
  (while (setq e (car (entsel "\n拾取曲线: "))) ;_可以循环选择
    ;;仅在第一段处绘制
    (setq sp (vlax-curve-getstartpoint e) ;_vlax-curve参数可以是 Entity 也可以是 Object
    p1 (vlax-curve-getpointatparam e 1.) ;_第二个点是 参数 1.0
    )
    (setq pt (mapcar '(lambda (x) (* x 0.5)) (mapcar '+ sp p1))) ;_求中点
    (Ea:AddDount ms pt 1. 2.) ;_调用绘制圆环函数
  )
  (vlax-release-object ms)
  (princ)
)[/pcode]
这里没有进行 ERROR 处理,这个应用中用户中断的机会就在 选择 时,中断后唯一的就是 ms 没有释放,其他代码没有影响

点评

我这个程序设计背景是当一条直线上有一个圆环,然后向沿直线上指定方向偏移指定的距离,你这个程序确实也很不错。  详情 回复 发表于 2013-6-3 16:16
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-6-3 16:16:37 | 显示全部楼层
eachy 发表于 2013-6-3 16:00
;;绘制圆环,这个经常用,写个函数
;;参数:中心点、半径、宽度
;;      这里参数给个 space 适用多数情 ...

我这个程序设计背景是当一条直线上有一个圆环,然后向沿直线上指定方向偏移指定的距离,你这个程序确实也很不错。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-14 19:48 , Processed in 0.306612 second(s), 62 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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