明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 11346|回复: 20

[原创] 判断点在封闭曲线的位置

  [复制链接]
发表于 2008-5-16 16:35:00 | 显示全部楼层 |阅读模式
本帖最后由 作者 于 2008-5-16 19:17:35 编辑

;;=======================================
;;  [原创] 判断点在封闭曲线的位置
;;  by caoyin @ www.mjtd.com
;;=======================================

;; 欢迎,大家帮忙测试,指正。抛砖引玉。。。

;; 参数 PT------任意点
;;      CURVE---任意封闭曲线
;; 返回 0------->在曲线上
;;      T------->在曲线内
;;      nil----->在曲线外
  1. (defun LT:PT-INCURVE (PT CURVE / GetInters OBJ MINPT MAXPT E PS LST X Y)
  2.   (defun GetInters (OBJ1 OBJ2 / PS LST)
  3.     (setq PS (vla-intersectwith OBJ1 OBJ2 0)
  4.           PS (vl-catch-all-apply 'vlax-safearray->list (list (vlax-variant-value PS)))
  5.     )
  6.     (if (and PS (not (vl-catch-all-error-p PS)))
  7.       (while (setq LST (cons (list (car PS) (cadr PS)) LST)
  8.                    PS  (cdddr PS)
  9.              )
  10.       )
  11.     )
  12.     LST
  13.   )
  14.   (if (equal (vlax-curve-getClosestPointTo CURVE PT) PT 1E-6)
  15.     0
  16.     (progn
  17.       (setq OBJ (vlax-ename->vla-object CURVE))
  18.       (vla-getboundingbox OBJ 'MINPT 'MAXPT)
  19.       (mapcar '(lambda (X) (set X (vlax-safearray->list (eval X)))) '(MINPT MAXPT))
  20.       (entmake (list '(0 . "LINE")
  21.                      (list 10 (car MINPT) (cadr PT))
  22.                      (list 11 (car MAXPT) (cadr PT))
  23.                      '(60 . 1)
  24.                )
  25.       )
  26.       (setq E (entlast) LST1 (GetInters OBJ (vlax-ename->vla-object E)))
  27.       (entdel E)
  28.       (if LST1
  29.         (setq LST1 (vl-remove-if
  30.                      '(lambda (X / PP A)
  31.                         (setq PP (vlax-curve-getParamAtPoint CURVE X)
  32.                               A  (angle '(0 0)
  33.                                         (vlax-curve-getFirstDeriv CURVE PP)
  34.                                  )
  35.                         )
  36.                         (or (equal A 0 1E-6)
  37.                             (equal A PI 1E-6)
  38.                             (equal A (* PI 2) 1E-6)
  39.                             (equal (fix PP) PP 1E-6)
  40.                         )
  41.                       )
  42.                      LST1
  43.                    )
  44.         )
  45.       )
  46.       (entmake (list '(0 . "LINE")
  47.                      (list 10 (car PT) (cadr MAXPT))
  48.                      (list 11 (car PT) (cadr MINPT))
  49.                      '(60 . 0)
  50.                )
  51.       )
  52.       (setq E (entlast) LST2 (GetInters OBJ (vlax-ename->vla-object E)))
  53.       (entdel E)
  54.       (if LST2
  55.         (setq LST2 (vl-remove-if
  56.                      '(lambda (X / PP A)
  57.                         (setq X  (vlax-curve-getClosestPointTo CURVE X)
  58.                               PP (vlax-curve-getParamAtPoint CURVE X)
  59.                               A  (angle (vlax-curve-getFirstDeriv CURVE PP)
  60.                                        '(0 0)
  61.                                 )
  62.                         )
  63.                         (or (equal A (/ PI 2) 1E-6)
  64.                             (equal A (* PI 1.5) 1E-6)
  65.                             (equal (fix PP) PP 1E-6)
  66.                         )
  67.                       )
  68.                      LST2
  69.                    )
  70.         )
  71.       )
  72.       (and LST1
  73.            LST2
  74.            (progn
  75.              (setq X (vl-sort-i (mapcar 'car (cons PT LST1)) '<)
  76.                    Y (length (member 0 X))
  77.              )
  78.              (and (zerop (rem Y 2)) (= (rem (- (length X) Y) 2) 1))
  79.            )
  80.            (progn
  81.              (setq X (vl-sort-i (mapcar 'cadr (cons PT LST2)) '<)
  82.                    Y (length (member 0 X))
  83.              )
  84.              (and (zerop (rem Y 2)) (= (rem (- (length X) Y) 2) 1))
  85.            )
  86.       )
  87.     )
  88.   )
  89. )
;;====================================================
;; 测试
  1. (defun c:test (/ CURVE PT X)
  2.   (if (and (setq CURVE (entsel "\n选择封闭曲线: "))
  3.            (setq CURVE (car CURVE))
  4.       )
  5.     (while (setq PT (getpoint "\n拾取任意点: "))
  6.       (setq X (LT:PT-INCURVE PT CURVE))
  7.       (princ "......在曲线")
  8.       (princ (cond ((= X 0) "上。") (X "内。") (T "外。")))
  9.     )
  10.   )
  11.   (princ)
  12. )

本帖子中包含更多资源

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

x
"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2008-5-16 18:42:00 | 显示全部楼层

试试看:

测试点在多义线内,并与其中一段在同一直线上(垂直或水平)

 楼主| 发表于 2008-5-16 19:20:00 | 显示全部楼层

试试看:
测试点在多义线内,并与其中一段在同一直线上(垂直或水平)

已经修正.

谢谢无痕斑竹提示,原来只考虑弧段的切点,没考虑顶点问题(红色为添加的顶点判断)

发表于 2008-5-17 10:17:00 | 显示全部楼层
好,,,,顶一个~
发表于 2009-9-7 20:08:00 | 显示全部楼层
好东东,顶一顶
发表于 2009-9-8 08:10:00 | 显示全部楼层
我原以为,通过给定点的任意方向的一条射线,如果与给定曲线交点数为单数个,就可判断为在曲线内。不知这个思路是否正确?另外,经试验intersectwith返回的交点数并不总是正确,不知何故,故该思路也不能实施。今天看此程序,如此复杂,是否可解释一下原理?
 楼主| 发表于 2009-9-16 20:17:00 | 显示全部楼层
本帖最后由 作者 于 2009-9-16 21:24:49 编辑

楼上所言不差,1楼的算法是复杂了,射线法可能是一种不错的算法。

射线法原理如下:

在通过指定的点绘制一条射线,有凸度的线排除掉切点,对有顶点的排除掉顶点,然后交点为奇数的即可判断为在曲线内。

正如你所说intersectwith存在的不确定因素,所以我还还有一种思路,不用intersectwith 的,不知可否:

1.将曲线写入特定的XDATA;

2.用XDATA作为过滤条件 (ssget "f" 。。。)创建选集

3.用 ssnamex 得到交点

4.用上面射线法排除顶点和切点

5.删除XDATA

我估计ssget和XDATA的效率很低,但是起码不用intersectwith了

发表于 2009-9-16 21:02:00 | 显示全部楼层

以前在网上搜集的一个判定点在封闭多线段内的

涉及到算法问题:

借花献佛大伙研究一下

(我是用线段拟合曲线然后调用了这个函数)

本帖子中包含更多资源

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

x
发表于 2009-9-16 21:02:00 | 显示全部楼层

谢谢caoyin的解释。

还可以利用wmf,用短线构造曲线,再拦选,并考虑只去掉这些短线的顶点。这样不够精确,估计效率也比较低,但在现在的计算机上效率应该不不是大问题。

发表于 2009-9-16 21:07:00 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-2-23 01:07 , Processed in 0.192585 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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