明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2447|回复: 20

[提问] 求大师帮忙看一下 关于PL线 "凹位"的判断

[复制链接]
发表于 2017-10-19 23:08:04 | 显示全部楼层 |阅读模式
本帖最后由 ysq101 于 2017-10-19 23:24 编辑



如上图...帮忙写个可以判断有这类多线段的LISP    找到后将它们全部改为红色只要有一处凹位就直接改成红色

谢谢大师


本帖子中包含更多资源

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

x
"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2017-10-20 10:09:48 | 显示全部楼层
本帖最后由 Gu_xl 于 2017-10-20 11:14 编辑

  1. ;请试用以下程序(未判断多段线是否是闭合多边形)
  2. (defun c:test()
  3.     (vl-load-com)
  4.     (setq cm (getvar "cmdecho"))
  5.     (setvar  "cmdecho" 0)
  6.     (command "_undo" "be")

  7.     (if (setq ssa (ssget '((0 . "*POLYLINE"))))
  8.         (progn
  9.              (setq m (sslength ssa) j 0)
  10.              (repeat m
  11.                   (setq obj  (vlax-ename->vla-object (ssname ssa j))
  12.                         pts  (vlax-get obj "Coordinates")
  13.                         name (vlax-get obj "ObjectName")
  14.                         ptb  nil
  15.                   )
  16.               
  17.                   (while pts
  18.                       (if (= name "AcDb3dPolyline")
  19.                           (setq ptb (cons (list (car pts) (cadr pts) (caddr pts)) ptb)
  20.                                 pts (cdr (cdr (cdr pts)))
  21.                           )
  22.                           (setq ptb (cons (list (car pts) (cadr pts)) ptb)
  23.                                 pts (cdr (cdr pts))
  24.                           )
  25.                       )
  26.                   )
  27.                
  28.                   (if (equal (car ptb) (last ptb) 1e-3)
  29.                       (setq ptb (cdr ptb))
  30.                   )
  31.                   (setq n (1- (length ptb)) i 0  slcj nil)

  32.                   (while (<= i n)
  33.                        (if (= i 0)
  34.                            (setq p1 (last ptb))
  35.                            (setq p1 (nth (1- i) ptb))
  36.                        )
  37.                        (setq p2 (nth i ptb))
  38.                        (if (= i n)
  39.                            (setq p3 (car ptb))
  40.                            (setq p3 (nth (1+ i) ptb))
  41.                        )
  42.                        (setq cj (car (trans (mapcar '- p1 p2) 1 (mapcar '- p3 p2)))
  43.                              slcj (cons cj slcj)
  44.                        )
  45.                      
  46.                        (if (not (or (vl-every '(lambda(x)(> x 0.0)) slcj)
  47.                                     (vl-every '(lambda(x)(< x 0.0)) slcj)
  48.                                 )
  49.                            )
  50.                            (progn
  51.                                (vlax-put obj "color" "1")
  52.                                (setq i n)
  53.                            )
  54.                       )
  55.                       (setq i (1+ i))
  56.                    )
  57.                   

  58.                   (setq j (1+ j))
  59.              )
  60.         )
  61.     )

  62.     (command "_undo" "e")
  63.     (setvar "cmdecho" cm)
  64.     (princ)
  65. )


点评

棒棒的。。就是这种效果。。。谢谢大师出手相助  发表于 2017-10-20 11:18

评分

参与人数 1明经币 +2 收起 理由
Gu_xl + 2 赞一个!

查看全部评分

发表于 2017-10-20 11:14:43 | 显示全部楼层
本帖最后由 llsheng_73 于 2017-10-20 15:04 编辑

对于封闭多段线,只要是凹点,那么该点及相邻两点组成的三角形的方向必然与该多段线整体方向相反
  1. (defun plxyz(e fuz / i p pt);多段线节点三维坐标,连续重合点只取一个,根据fuz阀值过滤接近点
  2.   (setq i(-(vlax-curve-getendparam e)(logand(cdr(assoc 70(entget e)))1)-1))
  3.   (while(setq i(1- i)p(vlax-curve-getpointatparam e i))
  4.     (setq pt(if(equal(car pt)p fuz)pt(cons p pt))))
  5.   )
  6. (defun 2area(pt)
  7.   (apply'+(mapcar'(lambda(x y)(-(*(car x)(cadr y))(*(car y)(cadr x))))(cons(last pt)pt)pt)))
  8. (defun pldir(e / p p1 p2);;e多段线图元或者对象
  9.   (vla-GetBoundingBox(if(=(type e)'ename)(vlax-ename->vla-object e)e)'p1'p2)
  10.   (mapcar'set'(p1 p2)(mapcar'vlax-safearray->list(list p1 p2)))
  11.   (2area(Mapcar'cdr(vl-sort(mapcar'(lambda(x)(setq p(vlax-curve-getclosestpointto e x))
  12.                                             (cons(vlax-curve-getparamatpoint e p)p))
  13.                                          (list(list(car p1)(cadr p2))p1(list(car p2)(cadr p1))p2))
  14.                                   '(lambda(x y)(<(car x)(car y)))))))
  15. (defun Pitpl(e / a p)
  16.   (setq p(plxyz e 0)
  17.         a(pldir e))
  18.   (vl-some'(lambda(x y z)(<(*(2area(list x y z))a)0))(cons(last p)p)p(cdr(append p(list(car p)))))
  19.   )
  20. (defun c:tt(/ s)
  21.   (if(setq s(ssget'((0 . "lwpolyline")(-4 . "&")(70 . 1))))
  22.     (foreach x(vl-remove'nil(mapcar'(lambda(x)(if(=(type(cadr x))'ename)(cadr x)))(ssnamex s)))
  23.       (if(Pitpl x)
  24.         (entmod(setq x(entget x)x(if(assoc 62 x)(subst'(62 . 1)(assoc 62 x)x)(append x'((62 . 1))))))))))


其实还有更简单的办法,凹点内角大于必定大于180,如果用angle来计算两条相邻边的角度后相减来得到内角,实际上是比较烦的。好在(n-1),n,(n+1)这样连续三点的内角可以把(n+1)转换到到n(n-1)直线,根据得到的坐标的来判断是否大于180,当然,这个判断的条件实际上也会因为点的方向不一样而完全相反,
  1. (defun plinexy(e)
  2.   (mapcar'cdr(vl-remove-if'(lambda(x)(/=(car x)10))(entget e))))
  3. (defun 2area(pt / a)
  4.   (setq a(apply'+(mapcar'(lambda(x y)(-(*(car x)(cadr y))(*(car y)(cadr x))))(cons(last pt)pt)pt))a(/ a(abs a))))
  5. (defun pitang(p p1 p2 a);;角p2 p1 p不大于180,a为给定方向
  6.   (<(*(car(trans(mapcar'- p1 p) 0 (mapcar'- p1 p2)))a)0))
  7. (defun pitpl(e / p a)
  8.   (setq p(plinexy e)
  9. a(2area p)
  10. p(vl-some'(lambda(x y z)(pitang x y z a))(cons(last p)p)p(cdr(append p(list(car p)))))))
  11. (defun c:tt(/ s)
  12.   (if(setq s(ssget'((0 . "lwpolyline")(-4 . "&")(70 . 1))))
  13.     (foreach x(vl-remove'nil(mapcar'(lambda(x)(if(=(type(cadr x))'ename)(cadr x)))(ssnamex s)))
  14.       (if(Pitpl x)
  15. (entmod(setq x(entget x)x(if(assoc 62 x)(subst'(62 . 1)(assoc 62 x)x)(append x'((62 . 1))))))))))


本帖子中包含更多资源

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

x

点评

那么该点及相邻两点组成的三角形的方向必然与该多段线整体方向相反 这思路赞一个。。  发表于 2017-10-20 11:19

评分

参与人数 1明经币 +2 收起 理由
Gu_xl + 2 赞一个!

查看全部评分

发表于 2017-10-20 10:42:50 | 显示全部楼层
本帖最后由 lijiao 于 2017-10-20 15:23 编辑

  1. (defun c:aopl (/ I SS)
  2.   (if (setq ss (ssget '((0 . "LWPOLYLINE") (70 . 1))))
  3.     (progn
  4.       (setq i -1)
  5.       (repeat (sslength ss)
  6.         (ao-p (ssname ss (setq i (1+ i))))
  7.       )
  8.     )
  9.   )
  10.   (princ)
  11. )
  12. (defun ao-p (pl / DATA PTS PTS1 PTS2 Y ZXS ZX)
  13.   (setq data (entget pl))
  14.   (setq pts (VL-REMOVE-IF-NOT '(lambda (y) (= (car y) 10)) data))
  15.   (setq pts (mapcar 'cdr pts))
  16.   (setq pts1 (cdr (append pts (list (car pts)))))
  17.   (setq pts2 (cdr (append pts1 (list (car pts1)))))
  18.   (setq pts (mapcar 'list pts pts1 pts2))
  19.   (setq        pts (mapcar '(lambda (y)
  20.                        (cons 'z y)
  21.                      )
  22.                     pts
  23.             )
  24.   )
  25.   (setq zxs (mapcar 'shiliang pts))  (setq zx (car zxs))
  26.   (setq zxs (VL-REMOVE-IF-NOT '(lambda (y) (= y zx)) zxs))
  27.   (if zxs
  28.     (progn
  29.       (if (assoc 62 data)
  30.         (setq data (subst '(62 . 1) (assoc 62 data) data))
  31.         (setq data (append data '((62 . 1))))
  32.       )
  33.       (entmod data)
  34.       t
  35.     )
  36.   )
  37. )
  38. (defun shiliang        (lst / CJ X1 X2 Y1 Y2)
  39.   (cond
  40.     ((member (car lst) '(+ -))
  41.      (apply 'mapcar lst)
  42.     )
  43.     ((= (car lst) 'x)
  44.      (mapcar 'set '(x1 y1) (cadr lst))
  45.      (mapcar 'set '(x2 y2) (caddr lst))
  46.      (- (* x1 y2) (* x2 y1))
  47.     )
  48.     ((= (car lst) 'z)
  49.      (setq cj (shiliang
  50.                 (list 'x
  51.                       (shiliang (list '- (caddr lst) (cadr lst)))
  52.                       (shiliang (list '- (cadddr lst) (cadr lst)))
  53.                 )
  54.               )
  55.      )
  56.      (cond
  57.        ((equal cj 0.0 0.0001) 0)
  58.        ((> cj 0.0) 1)
  59.        ((< cj 0.0) -1)
  60.      )
  61.     )
  62.   )
  63. )

评分

参与人数 1明经币 +2 收起 理由
Gu_xl + 2 赞一个!

查看全部评分

发表于 2017-10-19 23:15:21 来自手机 | 显示全部楼层
定制开发请去定制区。提问题起码要给个悬赏吧,什么都没有谁给你写?
 楼主| 发表于 2017-10-19 23:22:49 | 显示全部楼层
本帖最后由 ysq101 于 2017-10-19 23:27 编辑
水吉空 发表于 2017-10-19 23:15
定制开发请去定制区。提问题起码要给个悬赏吧,什么都没有谁给你写?

我错了............其实我一开始忘了点悬赏   明经币我还是有很多的太久没写LISP...
现在都像个大傻瓜一样...连LISP不读不懂了
 楼主| 发表于 2017-10-20 11:13:23 | 显示全部楼层

这算法。。。好像是用点来   “硬算”
 楼主| 发表于 2017-10-20 11:17:06 | 显示全部楼层



实测程序出错了。。。左下角一个没有凹位

本帖子中包含更多资源

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

x
发表于 2017-10-20 12:02:22 | 显示全部楼层
llsheng_73 发表于 2017-10-20 11:14
对于封闭多段线,只要是凹点,那么该点及相邻两点组成的三角形的方向必然与该多段线整体方向相反

旋向有正有反就可以判断了吧,是不是不用判断整个旋向?
发表于 2017-10-20 13:45:34 | 显示全部楼层
本帖最后由 llsheng_73 于 2017-10-20 15:21 编辑
自贡黄明儒 发表于 2017-10-20 12:02
旋向有正有反就可以判断了吧,是不是不用判断整个旋向?

整个多段线方向并不需要这条多段的所有点参与计算,实际上只需要取出四个点(其外接正矩形的四个角点到该多段线的最近点)按param排序就行
跟依次取三角形来计算旋向,直到乘积小于0或者所有三角形计算完再看乘积来判断有无凹点,应该区别不大
直接找出大于180的内角更简单也容易理解。。
  1. (defun plinexy(e)
  2.   (mapcar'cdr(vl-remove-if'(lambda(x)(/=(car x)10))(entget e))))
  3. (defun ptdir(pt / a);;
  4.   (if(zerop(setq a(apply'+(mapcar'(lambda(x y)(-(*(car x)(cadr y))(*(car y)(cadr x))))(cons(last pt)pt)pt))))
  5.     0(/ a(abs a))))
  6. (defun pitang(p p1 p2 a);;角p2 p1 p不大于180,a为给定方向
  7.   (<(*(car(trans(mapcar'- p1 p) 0 (mapcar'- p1 p2)))a)0))
  8. (defun pitpl(e / p a);;e是否有凹点
  9.   (setq p(plinexy e)
  10. a(ptdir p)
  11. p(vl-some'(lambda(x y z)(pitang x y z a))(cons(last p)p)p(cdr(append p(list(car p)))))))
  12. (defun pits(e / p a);;e的所有凹点
  13.   (setq p(plinexy e)
  14. a(ptdir p)
  15. p(vl-remove'nil(mapcar'(lambda(x y z)(if(pitang x y z a)y))(cons(last p)p)p(cdr(append p(list(car p))))))))
  16. (defun c:tt(/ s);;有凹点的多段线变红
  17.   (if(setq s(ssget'((0 . "lwpolyline")(-4 . "&")(70 . 1))))
  18.     (foreach x(vl-remove'nil(mapcar'(lambda(x)(if(=(type(cadr x))'ename)(cadr x)))(ssnamex s)))
  19.       (if(Pitpl x)
  20. (entmod(setq x(entget x)x(if(assoc 62 x)(subst'(62 . 1)(assoc 62 x)x)(append x'((62 . 1))))))))))
  21. (defun c:t1(/ s p);;凹点处画圆
  22.   (if(setq s(ssget'((0 . "lwpolyline")(-4 . "&")(70 . 1))))
  23.     (foreach x(vl-remove'nil(mapcar'(lambda(x)(if(=(type(cadr x))'ename)(cadr x)))(ssnamex s)))
  24.       (foreach i(pits x)
  25. (entmakex(mapcar'cons'(0 10 40 62)(list"circle"i 1 2)))))))


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

本版积分规则

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

GMT+8, 2025-1-3 03:32 , Processed in 0.202511 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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