找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 3017|回复: 33

[研讨] 关于多边形凸角凹角的判断

[复制链接]

已领礼包: 1268个

财富等级: 财源广进

发表于 2013-10-2 13:35:00 | 显示全部楼层 |阅读模式

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

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

×
对由直线边构成的多边形(pline),判断是凸角还是凹角,可以利用点集面积算法来求解,
1 获取pline顶点表
  1. (setq pts (xdrx_entity_getstretcpoint pl))

2 获取点集面积
  1. (setq mod (apply 'xdrx_points_area pts))

3 判断 pline 方向如果顺时针的话把曲线转向, 同时 Reverse pts
  1. (if (minusp mod)
  2.     (progn
  3.       (xdrx_curve_reverse pl))
  4.       (setq pts (reverse pts))
  5.     )
  6. )

4 如图示,三个点围成一个三角形进行判断,面积为负的为凹角
  1. (setq pts (append pts (list (car pts) (cadr pts))));_增加两个点判断起点处
  2. (while (cddr pts)
  3.     (mapcar 'set '(a b c) pts)
  4.    (if (minusp (xdrx_points_area a b c))
  5.      (progn ..... );_凹角处理代码
  6.      (progn ......);_凸角处理代码,注意判断三点一线情况
  7.    )
  8.    (setq pts (cdr pts));_处理下一角
  9. )

在角的处理上可以应用 xdrx_polyline 部分函数对 pline  灵活处理了
taojiao.jpg

评分

参与人数 1D豆 +5 收起 理由
xshrimp + 5 出题引导交流奖!

查看全部评分

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

已领礼包: 40个

财富等级: 招财进宝

发表于 2013-10-2 13:37:05 | 显示全部楼层
能适合所有的情况吗? 能不能找出一个反例出来?

点评

呵呵,我只想到了算法,反例没有想出来,逆时针凸包,面积为负的就凹进去,欢迎探讨  详情 回复 发表于 2013-10-2 13:40
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2013-10-2 13:40:21 | 显示全部楼层
newer 发表于 2013-10-2 13:37
能适合所有的情况吗? 能不能找出一个反例出来?

呵呵,我只想到了算法,反例没有想出来,逆时针凸包,面积为负的就凹进去,欢迎探讨:)

点评

计算多边形的凸包,如多边形面积比凸包面积小,多边形 自然是凹多边形 了!  详情 回复 发表于 2013-10-2 20:47
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 604个

财富等级: 财运亨通

发表于 2013-10-2 16:56:31 来自手机 | 显示全部楼层
三角形内取一点,判断这—点是否在多边形内,,可否?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 344个

财富等级: 日进斗金

发表于 2013-10-2 20:47:20 | 显示全部楼层
st788796 发表于 2013-10-2 13:40
呵呵,我只想到了算法,反例没有想出来,逆时针凸包,面积为负的就凹进去,欢迎探讨

计算多边形的凸包,如多边形面积比凸包面积小,多边形 自然是凹多边形 了!

点评

本意不是算多边形面积,看到机械加工上好像有一个应用,突出来的角扩大一个弧,如果是凹角就做一个 fillet ,这个算法三这方面应用  详情 回复 发表于 2013-10-2 22:20
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2013-10-2 22:20:01 | 显示全部楼层
牢固 发表于 2013-10-2 20:47
计算多边形的凸包,如多边形面积比凸包面积小,多边形 自然是凹多边形 了!

本意不是算多边形面积,看到机械加工上好像有一个应用,突出来的角扩大一个弧,如果是凹角就做一个 fillet ,这个算法三这方面应用

点评

那就没那么复杂了!先计算多边形面积(带正负号),逐个计算每个角点三角形面积,若面积符号和多边形面积符号一致,就是凸角,否则是凹角!  详情 回复 发表于 2013-10-2 23:10
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 344个

财富等级: 日进斗金

发表于 2013-10-2 23:10:19 | 显示全部楼层
本帖最后由 牢固 于 2013-10-2 23:12 编辑
st788796 发表于 2013-10-2 22:20
本意不是算多边形面积,看到机械加工上好像有一个应用,突出来的角扩大一个弧,如果是凹角就做一个 fille ...

那就没那么复杂了!先计算多边形面积(带正负号)(判断顺逆时针),再逐个计算每个角点三角形面积(判断顺逆时针) ,若三角形 面积符号和多边形面积符号一致(三角形和多边形同向),就是凸角,否则是凹角!

点评

是这样的,后面增加端点并设置bulge,在不事先设好逆时针情况下要多写一些判断  详情 回复 发表于 2013-10-3 01:34
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2013-10-3 01:34:42 来自手机 | 显示全部楼层
牢固 发表于 2013-10-2 23:10
那就没那么复杂了!先计算多边形面积(带正负号)(判断顺逆时针),再逐个计算每个角点三角形面积(判断 ...


是这样的,后面增加端点并设置bulge时,在不事先设好逆时针情况下要多写一些判断
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 685个

财富等级: 财运亨通

发表于 2013-10-3 23:05:39 | 显示全部楼层

我来分享网上下载的源码,,,好像也是根据三点面积来判断是  凹角还是凸角的...可以参考一下

原作者忘了是谁了~~~

  1. ;--------------------------倒内角-------------------------------------------
  2. (defun c:nn()
  3.   (setvar "cmdecho" 0)
  4.     (setq oldosmode (getvar "osmode"))
  5.   (setvar "osmode" 0)
  6.    (command "UNDO" "be")

  7.   
  8.   (setq dd 0.5)
  9.    (setq rr (getreal"\n请输入圆角半径:"))
  10.   (command "_fillet" "r" rr )
  11.   (setq ss1 (ssget (list (cons 0 "LWPOLYLINE"))))
  12.   (while(/= SS1 NIL)
  13.     (progn
  14.        (setq ii 0)
  15.        (repeat (sslength ss1)
  16.          (setq en1 (ssname ss1 ii))
  17.          (setq ii (+ ii 1))
  18.          (yp008chamfer en1)
  19.       )
  20.        (prompt "\n 完成 请检查:")
  21.        (setq ss1 (ssget (list (cons 0 "LWPOLYLINE"))))
  22.     )
  23.   )
  24.   (setvar "osmode" oldosmode)
  25.   (command "UNDO" "e")
  26.   (princ)
  27.   )


  28. (defun yp008chamfer(en1 / isclose i j ed1 pt1 pt2 pt3 lst1 lst2 )
  29.   (setq ed1 (entget en1))
  30.   (setq i 0)
  31.   (setq lst1 '()  lst2 '())
  32.   (repeat (length ed1)
  33.     (if(= (car (nth i ed1)) 10)
  34.        (setq lst1 (append lst1 (list (cdr (nth i ed1)))))n
  35.     )
  36.     (if(= (car (nth i ed1)) 42)
  37.        (setq lst2 (append lst2 (list (cdr (nth i ed1)))))
  38.     )
  39.     (setq i (+ i 1))
  40.   )

  41.   (setq isclose 0)
  42.   (if(= (cdr (assoc 70 ed1)) 1)
  43.      (progn
  44.         (setq isclose 1)
  45.         (setq lst1 (append lst1 (list (nth 0 lst1))))
  46.         (setq lst2 (append lst2 (list 0)))
  47.   ))
  48.   (if(equal (distance (nth 0 lst1) (nth (- (length lst1) 1) lst1)) 0.000000001)
  49.     (setq isclose 1)
  50.   )
  51.   (setq i 1)
  52.   (repeat (- (length lst1) 2)
  53.     (progn
  54.       (setq pt1 (nth (- i 1) lst1)    pt2 (nth i lst1)   pt3 (nth (+ i 1) lst1))
  55.       (setq ang1 (nth (- i 1) lst2)   ang2 (nth i lst2))
  56.       (if(and (equal ang1 0 0.000000001) (equal ang2 0 0.00000001))
  57.          (yp008c en1 pt1 pt2 pt3)
  58.       )
  59.       (setq i (+ i 1))
  60.     )
  61.   )
  62.   (if(= isclose 1)
  63.      (progn
  64.        (setq pt1 (nth (- (length lst1) 2) lst1)    pt2 (nth 0 lst1)   pt3 (nth 1 lst1))
  65.        (setq ang1 (nth (- (length lst1) 2) lst2)   ang2 (nth 0 lst2))
  66.        (if(and (equal ang1 0 0.000000001) (equal ang2 0 0.00000001))
  67.          (yp008c en1 pt1 pt2 pt3)
  68.        )
  69.   )  )

  70. )

  71. (defun yp008c(en1 pt1 pt2 pt3 / x1 x2 y1 y2 en4 en5)
  72.    (setq pt1 (trans pt1 0 1)   pt2 (trans pt2 0 1)   pt3 (trans pt3 0 1))
  73.    (if(and (> (distance pt1 pt2)  (* dd 2))  (> (distance pt3 pt2)  (* dd 2)))
  74.       (progn
  75.          (setq x1 (yp008x pt2 pt1 dd)
  76.                x2 (yp008x pt2 pt3 dd)
  77.                y1 (yp008y pt2 pt1 dd)
  78.                y2 (yp008y pt2 pt3 dd)
  79.          )
  80.          (command "_area" "o" en1)
  81.          (setq en4 (getvar "AREA"))
  82. ;(prompt (strcat "\n" (rtos x1 2 2) ";" (rtos y1 2 2)))
  83.          (command "_fillet"  (list x2 y2) (list x1 y1) )  ;;en5)
  84. ;(prompt (strcat "\n" (rtos x2 2 2) ";" (rtos y2 2 2)))
  85.          (command "_area" "o" en1)
  86.          (setq en5 (getvar "AREA"))
  87.          (IF(> EN4 EN5)
  88.             (progn
  89.               (command "u")
  90.               (command "u")
  91.               (command "u")
  92.          )   )

  93.      ;    (IF(> EN4 EN5) (COMMAND "UNDO" 2))
  94.         
  95.    )  )
  96. )

  97. (defun yp008x(pt2 pt1 d / x3 d1)
  98.    (setq d1 (distance pt2 pt1))
  99.    (if(equal (car pt1) (car pt2) 0.00000001)
  100.       (setq x3 (car pt1))
  101.       (setq x3 (+ (car pt2) (* (- (car pt1) (car pt2)) 0.25)))
  102.    )
  103. )
  104. (defun yp008y(pt2 pt1 d / x3 d1)
  105.    (setq d1 (distance pt2 pt1))
  106.    (if(equal (cadr pt1) (cadr pt2) 0.00000001)
  107.       (setq x3 (cadr pt1))
  108.       (setq x3 (+ (cadr pt2) (* (- (cadr pt1) (cadr pt2)) 0.25)))
  109.    )
  110. )


  111. ;----------------------倒外角-------------------------------------------------------
  112. (defun c:n()
  113.   (setvar "cmdecho" 0)
  114.   (setq oldosmode (getvar "osmode"))
  115.      (command "UNDO" "be")

  116.   (setq dd 0.5)  
  117.   (setq rr (getreal"\n请输入圆角半径:"))
  118.   (command "_fillet" "r" rr )
  119.     (setq ss1 (ssget (list (cons 0 "LWPOLYLINE"))))
  120.   (while(/= SS1 NIL)
  121.     (progn
  122.        (setq ii 0)
  123.        (repeat (sslength ss1)
  124.          (setq en1 (ssname ss1 ii))
  125.          (setq ii (+ ii 1))
  126.          (yp007chamfer en1)
  127.        )
  128.        (prompt "\n 完成 请检查:")
  129.        (setq ss1 (ssget (list (cons 0 "LWPOLYLINE"))))
  130.     )
  131.   )
  132.   (setvar "osmode" oldosmode)
  133.     (command "UNDO" "e")
  134.   (princ)
  135. )

  136. (defun yp007chamfer(en1 / isclose i j ed1 pt1 pt2 pt3 lst1 lst2 )
  137.   (setq ed1 (entget en1))
  138.   (setq i 0)
  139.   (setq lst1 '()  lst2 '())
  140.   (repeat (length ed1)
  141.     (if(= (car (nth i ed1)) 10)
  142.        (setq lst1 (append lst1 (list (cdr (nth i ed1)))))
  143.     )
  144.     (if(= (car (nth i ed1)) 42)
  145.        (setq lst2 (append lst2 (list (cdr (nth i ed1)))))
  146.     )
  147.     (setq i (+ i 1))
  148.   )

  149.   (setq isclose 0)
  150.   (if(= (cdr (assoc 70 ed1)) 1)
  151.      (progn
  152.         (setq isclose 1)
  153.         (setq lst1 (append lst1 (list (nth 0 lst1))))
  154.         (setq lst2 (append lst2 (list 0)))
  155.   ))
  156.   (if(equal (distance (nth 0 lst1) (nth (- (length lst1) 1) lst1))
  157. 0.000000001)
  158.     (setq isclose 1)
  159.   )
  160.   (setq i 1)
  161.   (repeat (- (length lst1) 2)
  162.     (progn
  163.       (setq pt1 (nth (- i 1) lst1)    pt2 (nth i lst1)   pt3 (nth (+ i 1)
  164. lst1))
  165.       (setq ang1 (nth (- i 1) lst2)   ang2 (nth i lst2))
  166.       (if(and (equal ang1 0 0.000000001) (equal ang2 0 0.00000001))
  167.          (yp007c en1 pt1 pt2 pt3)
  168.       )
  169.       (setq i (+ i 1))
  170.     )
  171.   )
  172.   (if(= isclose 1)
  173.      (progn
  174.        (setq pt1 (nth (- (length lst1) 2) lst1)    pt2 (nth 0 lst1)   pt3
  175. (nth 1 lst1))
  176.        (setq ang1 (nth (- (length lst1) 2) lst2)   ang2 (nth 0 lst2))
  177.        (if(and (equal ang1 0 0.000000001) (equal ang2 0 0.00000001))
  178.          (yp007c en1 pt1 pt2 pt3)
  179.        )
  180.   )  )

  181. )

  182. (defun yp007c(en1 pt1 pt2 pt3 / x1 x2 y1 y2 en4 en5)
  183.    (setq pt1 (trans pt1 0 1)   pt2 (trans pt2 0 1)   pt3 (trans pt3 0 1))
  184.    (if(and (> (distance pt1 pt2)  (* dd 2))  (> (distance pt3 pt2)  (* dd
  185. 2)))
  186.       (progn
  187.          (setq x1 (yp007x pt2 pt1 dd)
  188.                x2 (yp007x pt2 pt3 dd)
  189.                y1 (yp007y pt2 pt1 dd)
  190.                y2 (yp007y pt2 pt3 dd)
  191.          )
  192.          (command "_area" "o" en1)
  193.          (setq en4 (getvar "AREA"))
  194.          
  195.          (command "_fillet"  (list x2 y2) (list x1 y1) )  ;;en5)
  196.          (command "_area" "o" en1)
  197.          (setq en5 (getvar "AREA"))
  198.          (IF(< EN4 EN5) (COMMAND "UNDO" 2))
  199.         
  200.    )  )
  201. )

  202. (defun yp007x(pt2 pt1 d / x3 d1)
  203.    (setq d1 (distance pt2 pt1))
  204.    (if(equal (car pt1) (car pt2) 0.00000001)
  205.       (setq x3 (car pt1))
  206.       (setq x3 (+ (car pt2) (* (- (car pt1) (car pt2)) 0.5)))
  207.    )
  208. )
  209. (defun yp007y(pt2 pt1 d / x3 d1)
  210.    (setq d1 (distance pt2 pt1))
  211.    (if(equal (cadr pt1) (cadr pt2) 0.00000001)
  212.       (setq x3 (cadr pt1))
  213.       (setq x3 (+ (cadr pt2) (* (- (cadr pt1) (cadr pt2)) 0.5)))
  214.    )
  215. )

评分

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

查看全部评分

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

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2013-10-4 01:49:48 | 显示全部楼层
ysq101 发表于 2013-10-3 23:05
我来分享网上下载的源码,,,好像也是根据三点面积来判断是  凹角还是凸角的...可以参考一下

原作者忘了 ...

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

使用道具 举报

已领礼包: 182个

财富等级: 日进斗金

发表于 2013-10-4 13:15:48 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2013-10-4 15:06:32 来自手机 | 显示全部楼层
kcad2010 发表于 2013-10-4 13:15
看样子,好像是同行哦,做模具设计的吧?

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

使用道具 举报

已领礼包: 685个

财富等级: 财运亨通

发表于 2013-10-4 16:24:23 | 显示全部楼层
kcad2010 发表于 2013-10-4 13:15
看样子,好像是同行哦,做模具设计的吧?

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

使用道具 举报

已领礼包: 685个

财富等级: 财运亨通

发表于 2013-10-4 16:25:06 | 显示全部楼层
st788796 发表于 2013-10-4 01:49
Command 有时候不灵光,没有运行成功

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

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-15 11:46 , Processed in 0.222733 second(s), 66 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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