明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2754|回复: 14

[源码] 所有的点按照顺时针方向排序

[复制链接]
发表于 2018-4-6 11:05 | 显示全部楼层 |阅读模式
代码产生背景:
       在建筑模型绘图中,由于打灯光的需要,在建筑模型框架的内部需要做,万家灯火的框架,做成蜂窝状,每家窗户都有一个灯,模拟现实的灯光效果,通常是做成层层跑动的灯光,两路或者3路不同颜色变换的灯光,为了达到这种灯光效果,就需要CAD绘图员画出带灯孔的板和带凹槽的卡板,所以这个代码就出现了。对建筑模型行业了解的绘图员,都明白,灯孔板和卡板都是有规律的,所以用代码实现肯定能省不少时间,减少加班时间。
引用猫老师的话:“珍惜生命,提高工作效率”。
下图为:自动画万家灯火的灯孔板和带凹槽的卡板

代码的功能:点按照顺时针方向排序

  1. (defun ssinters  (sss / i num obj1 obj2 j interpts ptlist)
  2.   (setq  i   0
  3.   num (sslength sss)
  4.   )
  5.   (while (< i (1- num))
  6.     (setq obj1 (ssname sss i)
  7.     obj1 (vlax-ename->vla-object obj1)
  8.     j    (1+ i)
  9.     )
  10.     (while (< j num)
  11.       (setq obj2     (ssname sss j)
  12.       obj2     (vlax-ename->vla-object obj2)
  13.       interpts (vla-intersectwith
  14.            obj1
  15.            obj2
  16.            0
  17.          )
  18.       interpts (vlax-variant-value interpts)
  19.       )
  20.       (if (> (vlax-safearray-get-u-bound interpts 1) 0)
  21.   (progn
  22.     (setq  interpts
  23.      (vlax-safearray->list interpts)
  24.     )
  25.     (while (> (length interpts) 0)
  26.       (setq ptlist (cons (list (car interpts)
  27.              (cadr interpts)
  28.              (caddr interpts)
  29.              )
  30.              ptlist
  31.        )
  32.       )
  33.       (setq interpts (cdddr interpts))
  34.     )
  35.   )
  36.       )
  37.       (setq j (1+ j))
  38.     )
  39.     (setq i (1+ i))
  40.   )
  41.   ptlist
  42. )


  43. (defun HH:ssPts:Sort (ssPts KEY FUZZ / E EN FUN LST N);By 自贡黄明儒
  44.   ;;1 点列表排序
  45.   (defun sortpts (PTS FUN xyz FUZZ)
  46.     (vl-sort pts
  47.       '(lambda (a b)
  48.   (if (not (equal (xyz a) (xyz b) fuzz))
  49.     (fun (xyz a) (xyz b))
  50.   )
  51.        )
  52.     )
  53.   )
  54.   ;;2 排序先后
  55.   (defun sortpts1 (PTS KEY FUZZ)
  56.     (setq Key (vl-string->list Key))
  57.     (foreach xyz (reverse Key)
  58.       (cond ((< xyz 100)
  59.       (setq fun >)
  60.       (setq xyz (nth (- xyz 88) (list car cadr caddr)))
  61.      )
  62.      (T
  63.       (setq fun <)
  64.       (setq xyz (nth (- xyz 120) (list car cadr caddr)))
  65.      )
  66.       )
  67.       (setq Pts (sortpts Pts fun xyz fuzz))
  68.     )
  69.   )
  70.   ;;3 本程序主程序
  71.   (cond
  72.     ((= (type ssPts) 'PICKSET)
  73.      (repeat (setq n (sslength ssPts))
  74.        (if (and (setq e (ssname ssPts (setq n (1- n))))
  75.   (setq en (entget e))
  76.     )
  77.   (setq lst (cons (append (cdr (assoc 10 en)) (list e)) lst))
  78.        )
  79.      )
  80.      (mapcar 'last (sortpts1 lst KEY FUZZ))
  81.     )
  82.     ((Listp ssPts)
  83.       (cond
  84. ((vl-consp (car ssPts)) (sortpts1 ssPts KEY FUZZ))
  85. ((= (type (car ssPts)) 'ENAME)
  86.   (foreach e ssPts
  87.     (if (setq en (entget e))
  88.       (setq lst (cons (append (cdr (assoc 10 en)) (list e)) lst))
  89.     )
  90.   )
  91.   (mapcar 'last (sortpts1 lst KEY FUZZ))
  92. )
  93. (T
  94.   (cond ((equal key "X") (vl-sort ssPts '>))
  95.         ((equal key "x") (vl-sort ssPts '<))
  96.   )
  97. )
  98.       )
  99.     )
  100.   )
  101. )

  102. ;; Clockwise-p  -  Lee Mac
  103. ;; Returns T if p1,p2,p3 are clockwise oriented

  104. (defun LM:Clockwise-p ( p1 p2 p3 )
  105.     ((lambda ( n ) (< (car (trans p2 0 n)) (car (trans p1 0 n)))) (mapcar '- p1 p3))
  106. )

  107. ;;164.3 [功能] 多段线端点列表 By 自贡黄明儒
  108. ;;示例(HH:PtLists (car (entsel)))
  109. (defun HH:PtLists (en)
  110.   (mapcar 'cdr
  111.           (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget en))
  112.   )
  113. )


  114. ;(/ osmode_bak clayer_bak ss ss7 ss2 en pts n);猫老师编辑器变量自动生成
  115. (defun c:tt (/ osmode_bak clayer_bak ss ss7 ss2   p1 pts p2 p3 en n ss1  sss ptx lst pt)
  116. ;----开始系统变量备份----
  117. (command "undo" "be")
  118. (setvar "cmdecho" 0);_关闭命令提示
  119. (setq osmode_bak (getvar "osmode"));_记录捕捉
  120. (setvar "osmode" 0);_关闭捕捉
  121. (setq clayer_bak (getvar "clayer"));_记录当前图层
  122. ;----;----;----;----;----;----;----;----;----
  123. ;按照图层分选择集,为了求2个图层对象的交点
  124. (setq ss (ssget))

  125.   (command "select" ss  "")
  126.   (setq ss7 (ssget "p" '((8 . "ngc7"))))

  127.   (command "select" ss "")
  128.   (setq ss2 (ssget "p" '((8 . "ngc2"))))


  129. (setq en (ssname ss7 0))
  130. (setq pts (HH:PtLists en));HH:PtLists多段线端点列表 By 自贡黄明儒
  131. (setq n 0)

  132. (if (< (fix(vlax-curve-getEndParam en)) 2)
  133.     (progn
  134.     (dengg);一条线的时候
  135.   )
  136. )
  137. (if (> (fix(vlax-curve-getEndParam en)) 1)
  138.     (progn
  139.     (deng);多条线的时候
  140.   )
  141.   )


  142. ;----结束系统变量还原----
  143. (setvar "osmode" osmode_bak);_还原捕捉
  144. (setvar "clayer" clayer_bak);_还原图层
  145. (setvar "cmdecho" 1);_打开命令提示
  146. (command "undo" "e")
  147. (princ);_关闭程序返回值
  148.   )



  149. ;(/ p1 pts p2 p3 en n ss1 ss2 sss ptx lst pt)
  150. (defun deng ()
  151. (setq p1 (nth 0 pts)
  152.       p2 (nth 1 pts)
  153.       p3 (nth 2 pts)
  154. )
  155. (if (= (LM:Clockwise-p p1 p2 p3) nil); 判断顺时针和逆时针Clockwise-p  -  Lee Mac
  156.     (progn (setq pts(reverse pts)))
  157. )
  158. ;重复动作
  159. (repeat
  160.    (fix(vlax-curve-getEndParam en))
  161. (command "line" (nth n pts) (nth (1+ n) pts) "")
  162. (setq ss1 (entlast))
  163. (command "select" ss1 ss2 "")
  164. (setq sss (ssget "p" ))
  165. (setq ptx (ssinters sss));ssinters求交点,明经论坛里面的
  166. (command "erase" ss1 "")

  167. (setq lst (append (list  (nth n pts) (nth (1+ n) pts))  ptx))
  168. ;下面就是判断线的方向,根据方向,重新排序点
  169. (if (and(= (car(nth n pts)) (car(nth (1+ n) pts)))
  170.         (< (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
  171.      )
  172.    (progn(setq lst (HH:ssPts:Sort lst "y" 0.1)));点排序 HH:ssPts:Sort  By 自贡黄明儒
  173. )
  174. (if (and(= (car(nth n pts)) (car(nth (1+ n) pts)))
  175.         (> (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
  176.      )
  177.    (progn(setq lst (HH:ssPts:Sort lst "Y" 0.1)))
  178. )
  179. (if (and(= (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
  180.         (< (car(nth n pts)) (car(nth (1+ n) pts)))
  181.      )
  182.    (progn(setq lst (HH:ssPts:Sort lst "x" 0.1)))
  183. )
  184. (if (and(= (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
  185.         (> (car(nth n pts)) (car(nth (1+ n) pts)))
  186.      )
  187.    (progn(setq lst (HH:ssPts:Sort lst "X" 0.1)))
  188. )
  189. (if (and(< (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
  190.         (< (car(nth n pts)) (car(nth (1+ n) pts)))
  191.      )
  192.    (progn(setq lst (HH:ssPts:Sort lst "xy" 0.1)))
  193. )
  194. (if (and(> (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
  195.         (> (car(nth n pts)) (car(nth (1+ n) pts)))
  196.      )
  197.    (progn(setq lst (HH:ssPts:Sort lst "XY" 0.1)))
  198. )
  199. (if (and(> (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
  200.         (< (car(nth n pts)) (car(nth (1+ n) pts)))
  201.      )
  202.    (progn(setq lst (HH:ssPts:Sort lst "Yx" 0.1)))
  203. )
  204. (if (and(< (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
  205.         (> (car(nth n pts)) (car(nth (1+ n) pts)))
  206.      )
  207.    (progn(setq lst (HH:ssPts:Sort lst "Xy" 0.1)))
  208. )

  209. (command "-layer" "s" "ngc1" "")

  210. (entmake (append    (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 (length lst)))
  211.       (mapcar '(lambda (pt)(cons 10 pt)) lst ))
  212.   )
  213.   (setq n (1+ n))
  214. )
  215. )



和上面的代码一样


希望能得到前辈的指点,上面就是判断线的方向的源代码,根据方向,重新排序点,应该有更加简单的办法,里面函数的出处我都标明了。

本帖子中包含更多资源

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

x

评分

参与人数 2明经币 +2 收起 理由
Bao_lai + 1 神马都是浮云
USER2128 + 1 赞一个!

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2021-3-25 21:54 | 显示全部楼层
(defun ssinters  (sss / i num obj1 obj2 j interpts ptlist)
  (setq  i   0
  num (sslength sss)
  )
  (while (< i (1- num))
    (setq obj1 (ssname sss i)
    obj1 (vlax-ename->vla-object obj1)
    j    (1+ i)
    )
    (while (< j num)
      (setq obj2     (ssname sss j)
      obj2     (vlax-ename->vla-object obj2)
      interpts (vla-intersectwith
           obj1
           obj2
           0
         )
      interpts (vlax-variant-value interpts)
      )
      (if (> (vlax-safearray-get-u-bound interpts 1) 0)
  (progn
    (setq  interpts
     (vlax-safearray->list interpts)
    )
    (while (> (length interpts) 0)
      (setq ptlist (cons (list (car interpts)
             (cadr interpts)
             (caddr interpts)
             )
             ptlist
       )
      )
      (setq interpts (cdddr interpts))
    )
  )
      )
      (setq j (1+ j))
    )
    (setq i (1+ i))
  )
  ptlist
)


(defun HH:ssPts:Sort (ssPts KEY FUZZ / E EN FUN LST N);By 自贡黄明儒
  ;;1 点列表排序
  (defun sortpts (PTS FUN xyz FUZZ)
    (vl-sort pts
      '(lambda (a b)
  (if (not (equal (xyz a) (xyz b) fuzz))
    (fun (xyz a) (xyz b))
  )
       )
    )
  )
  ;;2 排序先后
  (defun sortpts1 (PTS KEY FUZZ)
    (setq Key (vl-string->list Key))
    (foreach xyz (reverse Key)
      (cond ((< xyz 100)
      (setq fun >)
      (setq xyz (nth (- xyz 88) (list car cadr caddr)))
     )
     (T
      (setq fun <)
      (setq xyz (nth (- xyz 120) (list car cadr caddr)))
     )
      )
      (setq Pts (sortpts Pts fun xyz fuzz))
    )
  )
  ;;3 本程序主程序
  (cond
    ((= (type ssPts) 'PICKSET)
     (repeat (setq n (sslength ssPts))
       (if (and (setq e (ssname ssPts (setq n (1- n))))
  (setq en (entget e))
    )
  (setq lst (cons (append (cdr (assoc 10 en)) (list e)) lst))
       )
     )
     (mapcar 'last (sortpts1 lst KEY FUZZ))
    )
    ((Listp ssPts)
      (cond
((vl-consp (car ssPts)) (sortpts1 ssPts KEY FUZZ))
((= (type (car ssPts)) 'ENAME)
  (foreach e ssPts
    (if (setq en (entget e))
      (setq lst (cons (append (cdr (assoc 10 en)) (list e)) lst))
    )
  )
  (mapcar 'last (sortpts1 lst KEY FUZZ))
)
(T
  (cond ((equal key "X") (vl-sort ssPts '>))
        ((equal key "x") (vl-sort ssPts '<))
  )
)
      )
    )
  )
)

;; Clockwise-p  -  Lee Mac
;; Returns T if p1,p2,p3 are clockwise oriented

(defun LM:Clockwise-p ( p1 p2 p3 )
    ((lambda ( n ) (< (car (trans p2 0 n)) (car (trans p1 0 n)))) (mapcar '- p1 p3))
)

;;164.3 [功能] 多段线端点列表 By 自贡黄明儒
;;示例(HH<img src="static/image/smiley/default/tongue.gif" smilieid="7" border="0" alt="" />tLists (car (entsel)))
(defun HH<img src="static/image/smiley/default/tongue.gif" smilieid="7" border="0" alt="" />tLists (en)
  (mapcar 'cdr
          (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget en))
  )
)


;(/ osmode_bak clayer_bak ss ss7 ss2 en pts n);猫老师编辑器变量自动生成
(defun c:tt (/ osmode_bak clayer_bak ss ss7 ss2   p1 pts p2 p3 en n ss1  sss ptx lst pt)
;----开始系统变量备份----
(command "undo" "be")
(setvar "cmdecho" 0);_关闭命令提示
(setq osmode_bak (getvar "osmode"));_记录捕捉
(setvar "osmode" 0);_关闭捕捉
(setq clayer_bak (getvar "clayer"));_记录当前图层
;----;----;----;----;----;----;----;----;----
;按照图层分选择集,为了求2个图层对象的交点
(setq ss (ssget))

  (command "select" ss  "")
  (setq ss7 (ssget "p" '((8 . "ngc7"))))

  (command "select" ss "")
  (setq ss2 (ssget "p" '((8 . "ngc2"))))


(setq en (ssname ss7 0))
(setq pts (HH<img src="static/image/smiley/default/tongue.gif" smilieid="7" border="0" alt="" />tLists en));HH<img src="static/image/smiley/default/tongue.gif" smilieid="7" border="0" alt="" />tLists多段线端点列表 By 自贡黄明儒
(setq n 0)

(if (< (fix(vlax-curve-getEndParam en)) 2)
    (progn
    (dengg);一条线的时候
  )
)
(if (> (fix(vlax-curve-getEndParam en)) 1)
    (progn
    (deng);多条线的时候
  )
  )


;----结束系统变量还原----
(setvar "osmode" osmode_bak);_还原捕捉
(setvar "clayer" clayer_bak);_还原图层
(setvar "cmdecho" 1);_打开命令提示
(command "undo" "e")
(princ);_关闭程序返回值
  )



;(/ p1 pts p2 p3 en n ss1 ss2 sss ptx lst pt)
(defun deng ()
(setq p1 (nth 0 pts)
      p2 (nth 1 pts)
      p3 (nth 2 pts)
)
(if (= (LM:Clockwise-p p1 p2 p3) nil); 判断顺时针和逆时针Clockwise-p  -  Lee Mac
    (progn (setq pts(reverse pts)))
)
;重复动作
(repeat
   (fix(vlax-curve-getEndParam en))
(command "line" (nth n pts) (nth (1+ n) pts) "")
(setq ss1 (entlast))
(command "select" ss1 ss2 "")
(setq sss (ssget "p" ))
(setq ptx (ssinters sss));ssinters求交点,明经论坛里面的
(command "erase" ss1 "")

(setq lst (append (list  (nth n pts) (nth (1+ n) pts))  ptx))
;下面就是判断线的方向,根据方向,重新排序点
(if (and(= (car(nth n pts)) (car(nth (1+ n) pts)))
        (< (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
     )
   (progn(setq lst (HH:ssPts:Sort lst "y" 0.1)));点排序 HH:ssPts:Sort  By 自贡黄明儒
)
(if (and(= (car(nth n pts)) (car(nth (1+ n) pts)))
        (> (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
     )
   (progn(setq lst (HH:ssPts:Sort lst "Y" 0.1)))
)
(if (and(= (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
        (< (car(nth n pts)) (car(nth (1+ n) pts)))
     )
   (progn(setq lst (HH:ssPts:Sort lst "x" 0.1)))
)
(if (and(= (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
        (> (car(nth n pts)) (car(nth (1+ n) pts)))
     )
   (progn(setq lst (HH:ssPts:Sort lst "X" 0.1)))
)
(if (and(< (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
        (< (car(nth n pts)) (car(nth (1+ n) pts)))
     )
   (progn(setq lst (HH:ssPts:Sort lst "xy" 0.1)))
)
(if (and(> (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
        (> (car(nth n pts)) (car(nth (1+ n) pts)))
     )
   (progn(setq lst (HH:ssPts:Sort lst "XY" 0.1)))
)
(if (and(> (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
        (< (car(nth n pts)) (car(nth (1+ n) pts)))
     )
   (progn(setq lst (HH:ssPts:Sort lst "Yx" 0.1)))
)
(if (and(< (cadr(nth n pts)) (cadr(nth (1+ n) pts)))
        (> (car(nth n pts)) (car(nth (1+ n) pts)))
     )
   (progn(setq lst (HH:ssPts:Sort lst "Xy" 0.1)))
)

(command "-layer" "s" "ngc1" "")

(entmake (append    (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 (length lst)))
      (mapcar '(lambda (pt)(cons 10 pt)) lst ))
  )
  (setq n (1+ n))
)
)



好东西

点评

用好了,能实现好多的功能,里面有好多的函数  发表于 2021-3-30 13:31
回复 支持 1 反对 0

使用道具 举报

发表于 2021-3-28 21:20 | 显示全部楼层
流氓兔 发表于 2021-3-25 21:54
(defun ssinters  (sss / i num obj1 obj2 j interpts ptlist)
  (setq  i   0
  num (sslength sss)

请问老师,这个是按线顺序排点吗。

点评

是按照整体线的方向来确定点的位置,有了点的位置就可以关联实现其他功能  发表于 2021-3-30 13:31
 楼主| 发表于 2018-4-6 11:08 | 显示全部楼层
我自己做的工具箱,已经发布在论坛的工具篇
春婵建筑模型CAD绘图工具箱
http://bbs.mjtd.com/forum.php?mo ... &fromuid=363233
(出处: 明经CAD社区)
发表于 2018-4-7 10:14 | 显示全部楼层
楼主厉害啊,
发表于 2020-11-25 11:43 | 显示全部楼层
顶起顶起,,,,期待楼主的更新
发表于 2020-12-1 20:50 | 显示全部楼层
非常好的代码,谢谢分享啊。
发表于 2021-4-25 17:20 | 显示全部楼层
找了好长时间终于找到了
 楼主| 发表于 2021-4-26 16:40 | 显示全部楼层
LIULISHENG 发表于 2021-4-25 17:20
找了好长时间终于找到了

还能有好多的拓展代码
发表于 2021-4-26 18:30 | 显示全部楼层
咋没看明白咋回事呢,是只能判断多段线吗
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-20 08:26 , Processed in 1.216371 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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