明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 5677|回复: 28

[源码] 给新手练手--快速动态阵列(单向)

  [复制链接]
发表于 2021-3-2 00:21:03 | 显示全部楼层 |阅读模式
本帖最后由 print1985 于 2021-3-2 11:40 编辑

快速动态阵列(单向),程序比较好玩,也很实用
代码有大量注释(;后为代码注释),新手可以用来练手
觉得有用的可以点个赞,谢谢~~

部分代码来自论坛,感谢各位大神
技术含量不高,但是水平有限错误难免,如有问题请留言




  1. ;快速动态阵列zz
  2. ;为防止卡顿最多阵列100次,完全够用了
  3. (vl-load-com)
  4. (defun c:zz ( / *error* ang copy-fx copyn dist dist-x dist-y end-pt eraseyn gbydjl-x gbydjl-y i lastent m msg ms-pt ms-pt-x ms-pt-y p1 p2 pt pt-x pt-y snap ss sslst ss-new)
  5.   (defun *error* (msg)  ;错误处理函数
  6.     (if snap (setvar "osmode" snap)) ;恢复捕捉
  7.     (if (< 18 (atoi (substr (getvar "acadver") 1 2))) ;判断CAD版本,高版本用command-s
  8.       (command-s "undo" "e") ;CAD高版本用
  9.       (command "undo" "e")   ;低版本用
  10.     )
  11.     (setvar "cmdecho" 1) ;打开命令行提示
  12.     (princ msg)
  13.   )

  14.   (if (setq ss (ssget))
  15.     (progn
  16.       (setvar "cmdecho" 0) ;关闭命令行提示
  17.       (vl-cmdf "undo" "be") ;命令开始标记
  18.       (setq snap (getvar "osmode")) ;取得捕捉参数
  19.       (if (setq p1 (getpoint "\n点取复制的起点:"))
  20.         (if (setq p2 (getpoint p1 "\n点取或输入复制距离:"))
  21.           (progn
  22.             (setq dist   (distance p1 p2) ;复制距离
  23.                   dist-x (abs (- (car p1) (car p2))) ;x轴复制距离
  24.                   dist-y (abs (- (cadr p1) (cadr p2))) ;y轴复制距离
  25.                   ang    (angle p1 p2)
  26.                   end-pt p1 ;终点
  27.                   pt     p2 ;光标移动距离判断基准值
  28.                   i      0  ;最大阵列/复制次数
  29.                   m      T  ;提示超100个,只提示一次,防止卡顿
  30.             )
  31.             (if (> dist-x dist-y)  ;复制X/Y大方向判断
  32.               (if (< (car p1) (car p2))
  33.                 (setq copy-fx "x+") ;X+方向
  34.                 (setq copy-fx "x-") ;X-方向
  35.               )
  36.               (if (< (cadr p1) (cadr p2))
  37.                 (setq copy-fx "y+") ;y+方向
  38.                 (setq copy-fx "y-") ;y-方向
  39.               )
  40.             )
  41.             (while
  42.               (or (and (setq ms-pt (grread t 4 4)) (= (car ms-pt) 5))
  43.                   (and (= (car ms-pt) 2) (= (cadr ms-pt) 15))
  44.               )
  45.               (setq ms-pt-x  (car (cadr ms-pt))  ;当前光标x坐标
  46.                     ms-pt-y  (cadr (cadr ms-pt)) ;当前光标y坐标
  47.                     pt-x     (car pt)
  48.                     pt-y     (cadr pt)
  49.                     gbydjl-x (abs (- ms-pt-x pt-x)) ;x轴光标移动距离
  50.                     gbydjl-y (abs (- ms-pt-y pt-y)) ;y轴光标移动距离
  51.               )
  52.               (cond  ;复制/删除次数
  53.                 ((= copy-fx "x+")
  54.                  (progn
  55.                    (setq copyn (fix (/ gbydjl-x dist-x)))
  56.                    (setq eraseyn (- ms-pt-x pt-x))
  57.                  )
  58.                 )
  59.                 ((= copy-fx "x-")
  60.                  (progn
  61.                    (setq copyn (fix (/ gbydjl-x dist-x)))
  62.                    (setq eraseyn (- pt-x ms-pt-x))
  63.                  )
  64.                 )
  65.                 ((= copy-fx "y+")
  66.                  (progn
  67.                    (setq copyn (fix (/ gbydjl-y dist-y)))
  68.                    (setq eraseyn (- ms-pt-y pt-y))
  69.                  )
  70.                 )
  71.                 ((= copy-fx "y-")
  72.                  (progn
  73.                    (setq copyn (fix (/ gbydjl-y dist-y)))
  74.                    (setq eraseyn (- pt-y ms-pt-y))
  75.                  )
  76.                 )
  77.               )
  78.               (if (and (> copyn 0) (< copyn 100) (> eraseyn 0))  ;复制对象
  79.                 (progn
  80.                   (setvar "osmode" 0) ;关闭捕捉
  81.                   (repeat copyn
  82.                     (if (and (< i 100) (>= i 0))
  83.                       (progn
  84.                         (setq end-pt (polar end-pt ang dist)) ;终点
  85.                         (setq pt (polar end-pt ang dist))
  86.                         (setq lastent (entlast))
  87.                         (vl-cmdf "copy" ss "" p1 end-pt) ;复制
  88.                         (while (/= 0 (getvar "cmdactive")) (command pause)) ;等待命令完成
  89.                         (setq ss-new (ent_from lastent)) ;复制后新产生的图元选择集
  90.                         (setq sslst (append sslst (list ss-new)))
  91.                         (setq i (length sslst))
  92.                       )
  93.                       (if (and (> i 99) m)
  94.                         (progn
  95.                           (setq m nil)
  96.                           (princ "\n一次复制对象超过100个,为防止卡死,已停止复制!")
  97.                         )
  98.                       )
  99.                     )
  100.                   )
  101.                   (setvar "osmode" snap) ;打开捕捉
  102.                 )
  103.                 (if (and (> i 99) m)
  104.                   (progn
  105.                     (setq m nil)
  106.                     (princ "\n一次复制对象超过100个,为防止卡死,已停止复制!")
  107.                   )
  108.                 )
  109.               )
  110.               (if (and (> copyn 0) (< eraseyn 0) sslst (>= i 0))  ;删除对象
  111.                 (progn
  112.                   (if (not m)
  113.                     (princ "\n") ;换行
  114.                   )
  115.                   (repeat copyn
  116.                     (if (and (< i 101) (>= i 0) sslst)
  117.                       (progn
  118.                         (setq pt end-pt)
  119.                         (setq end-pt (polar end-pt (+ ang pi) dist))
  120.                         (vl-cmdf "erase" (car (reverse sslst)) "") ;删除
  121.                         (while (/= 0 (getvar "cmdactive")) (command pause)) ;等待命令完成
  122.                         (setq sslst (reverse (nth_del (reverse sslst) 0)))
  123.                         (setq i (length sslst))
  124.                         (setq m T)
  125.                       )
  126.                     )
  127.                   )
  128.                 )
  129.               )
  130.             )
  131.           )
  132.         )
  133.       )
  134.       (vl-cmdf "undo" "e") ;命令结束标记
  135.       (setvar "cmdecho" 1) ;打开命令行提示
  136.     )
  137.   )
  138.   (princ)
  139. )

  140. ;返回新产生图元选择集-来自论坛
  141. (defun ent_from (e / ss sn)
  142.   (if (/= (type e) (quote ename))
  143.     (alert "parameter error in ent_from")
  144.   )
  145.   (setq ss (ssadd))
  146.   (while e
  147.     (setq e (entnext e))
  148.     (if e
  149.       (progn
  150.         (setq sn (cdr (assoc 0 (entget e))))
  151.         (if (not (member sn (quote ("ATTRIB" "VERTEX" "SEQEND"))))
  152.           (setq ss (ssadd e ss))
  153.         )
  154.       )
  155.     )
  156.   )
  157.   ss
  158. )

  159. ;删除表内第n个元素-来自论坛
  160. (defun nth_del (lst n)
  161.   (vl-remove-if '(lambda (x) (= (vl-position x lst) n)) lst)
  162. )






评分

参与人数 4明经币 +4 收起 理由
muwind + 1
tigcat + 1 很给力!
USER2128 + 1 赞一个!
start4444 + 1 赞一个!

查看全部评分

"觉得好,就打赏"
    共1人打赏
发表于 2021-5-31 23:25:39 | 显示全部楼层
本帖最后由 1028695446 于 2021-5-31 23:36 编辑

整合LEE MAC大神的GRTEXT函数,随光标动态显示已复制次数

本帖子中包含更多资源

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

x

点评

很棒  发表于 2021-6-1 23:39
回复 支持 3 反对 0

使用道具 举报

发表于 2021-3-3 10:46:06 | 显示全部楼层
和这个差不多,这是chenqj写的,大家可以对比下,看哪个更适合自己
  1. ;;; the following code are writen by qjchen                                ;
  2. ;;; Purpose: To dynamic copy Object in one way                             ;
  3. ;;; Thanks to: lushui2 (The original idea Author)                          ;
  4. ;;;            Andera (He post a very cool Dynamic Array rountine)         ;
  5. ;;;                  at http://www.theswamp.org/index.php?topic=26633.5    ;
  6. ;;; Version v 1.0 2011.03.15                                               ;
  7. ;;; Http://chenqj.blogspot.com                                             ;
  8. ;;; ========================================================================

  9. ;;; =======================================================================;
  10. ;;; The main function                                                      ;
  11. ;;; =======================================================================;
  12. (vl-load-com)
  13. (defun c:zf ( / dir gr nx p0 px pxv ss ss1 vecx)
  14.   (setq        ss (std-sslist (ssget))
  15.         p0 (getpoint "\n指定基点:") px (getpoint p0 "\n指定下一点:")
  16.         vecx (mapcar '- px p0)
  17.   )
  18.   (prompt "\nThe end point:")
  19.   (while (= (car (setq gr (grread nil 5 0))) 5)
  20.     (if        ss1 (q:ss:del ss1))
  21.     (redraw)
  22.     (setq pxv (mapcar '- (inters (cadr gr) (polar (cadr gr) (+ (/ pi 2.0) (angle px p0)) 1.0) p0 px nil) p0))
  23.     (if (< (setq nx  (fix (/ (caddr (trans pxv 0 vecx)) (caddr (trans vecx 0 vecx))))) 0)
  24.            (setq dir -1 nx (- nx)) (setq dir 1))
  25.     (setq ss1 (q:ss:dyngen ss nx vecx dir))
  26.     (grdraw p0 (mapcar '+ p0 pxv) 3 1)
  27.   )
  28.   (princ)
  29. )

  30. ;;; =======================================================================;
  31. ;;; by qjchen, copy ss according to the direction and vector               ;
  32. ;;; =======================================================================;
  33. (defun q:ss:dyngen (sslst n v dir / i matlist obj1 ss transmat xobj)
  34.   (setq ss (ssadd))
  35.   (foreach x sslst
  36.     (setq xobj (vlax-ename->vla-object x) i 1)
  37.     (repeat n
  38.       (setq obj1 (vla-copy xobj)
  39.             matList (list (list 1 0 0 (* i (car v) dir)) (list 0 1 0 (* i (cadr v) dir)) '(0 0 1 0) '(0 0 0 1))
  40.             transmat (vlax-tmatrix matlist))
  41.       (vla-transformby obj1 transMat)
  42.       (ssadd (vlax-vla-object->ename obj1) ss)
  43.       (setq i (1+ i))
  44.     )
  45.   )
  46.   ss
  47. )

  48. ;;; =======================================================================;
  49. ;;; by qjchen, entdel ss                                                   ;
  50. ;;; =======================================================================;
  51. ;; (setq a (ssget))                                                        ;
  52. ;; (q:ss:del a)                                                            ;
  53. ;;; =======================================================================;
  54. (defun q:ss:del        (ss / i)
  55.   (setq i 0)
  56.   (repeat (sslength ss)
  57.     (entdel (ssname ss i))
  58.     (setq i (1+ i))
  59.   )
  60. )
  61. ;;; =======================================================================;
  62. ;;; by qjchen, 2 ss add                                                    ;
  63. ;;; =======================================================================;
  64. (defun q:ss:add        (ss1 ss2 / i)
  65.   (setq i -1)
  66.   (repeat (sslength ss2)
  67.     (setq i (1+ i))
  68.     (setq ss1 (ssadd (ssname ss2 i) ss1))
  69.   )
  70.   ss1
  71. )
  72. ;;; =======================================================================;
  73. ;;; selection to list, by Reini Urban                                      ;
  74. ;;; =======================================================================;
  75. (defun std-sslist  (ss / n lst)
  76.   (if        (eq 'pickset (type ss))
  77.     (repeat (setq n (fix (sslength ss))) ; fixed
  78.       (setq lst (cons (ssname ss (setq n (1- n))) lst))))
  79. )


  80. (princ "by qjchen@gmail.com, To dynamic Array object, the command is Test")
发表于 2022-10-26 21:56:04 | 显示全部楼层
甘大师,这个程序很好用,最近我遇到麻烦,有一个很好的想法,目前找遍了论坛还没有类似的功能,我们这个行业有时候一个零件需要做好几个,需要连续复制,但是零件都是要有间距的,目前还没有等间距的复制功能,大概意思是这样的,选择一个图元  然后会提示输入间距是多少,然后连续复制,(举个例子,复制10mm*10mm的方块  输入命令,选择10*10矩形 ,提示间距是多少,比如输入2,然后复制矩形每一个距离是12mm,只需要支持横着或者竖着复制,任何按横竖的方向复制,按一下空格就复制一个esc取消)
发表于 2021-3-2 10:50:42 | 显示全部楼层
一看注释就慌神了。最怕注释比例太多,卡
 楼主| 发表于 2021-3-2 10:56:34 | 显示全部楼层
tigcat 发表于 2021-3-2 10:50
一看注释就慌神了。最怕注释比例太多,卡

我晕 不是cad注释 是代码的注释。。。  就是备注代码的作用
发表于 2021-3-2 21:00:38 | 显示全部楼层

对比一下天正的功能。
发表于 2021-3-2 22:02:53 | 显示全部楼层
print1985 发表于 2021-3-2 10:56
我晕 不是cad注释 是代码的注释。。。  就是备注代码的作用

那就不怕了,我好好看看。
 楼主| 发表于 2021-3-3 16:59:56 | 显示全部楼层
luyu9635 发表于 2021-3-3 10:46
和这个差不多,这是chenqj写的,大家可以对比下,看哪个更适合自己

试用了一下 他是用的矩阵 大量的VL高级函数 我完全不会 但是有个问题 他一直在循环复制 阵列对象稍微多一点就非常卡 甚至卡很久 阵列同样多的对象 你可以对比一下2个程序的速度。
发表于 2021-3-7 16:55:22 | 显示全部楼层
print1985 发表于 2021-3-3 16:59
试用了一下 他是用的矩阵 大量的VL高级函数 我完全不会 但是有个问题 他一直在循环复制 阵列对象稍微多一 ...

您说的对,对象多时他这个会很卡,你的不会,少的时候不会卡,您的程序我建议改成两点(跟原始命令一样),不要另外去量取距离了,省一个步骤,更符合用户习惯一点
 楼主| 发表于 2021-3-7 22:35:49 | 显示全部楼层
luyu9635 发表于 2021-3-7 16:55
您说的对,对象多时他这个会很卡,你的不会,少的时候不会卡,您的程序我建议改成两点(跟原始命令一样) ...

不懂你的意思
程序本来就是只选择2个点开始阵列啊 并没有多余的量取距离 起点和终点 既是方向也是距离 和你发的程序一样的 不知道你想要什么样的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 09:55 , Processed in 0.191815 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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