本帖最后由 自贡黄明儒 于 2024-3-28 08:34 编辑
判断:一个点在封闭曲线内
在acad中,使用bloy,效果不错,基本上是万能的。不仅仅是封闭曲线,任何选择集都可以。
但在bcad中就不行了。我按照老迈的办法,使用(command "_.boundary" "a" "i" "y" "b" "n" ss "" "" "non" p "")
效果不好,改为caoyin版主的办法,效果也不好
找度娘,搜到结果如下
;;;1,如果该直线与封闭图形无交点或只有一个交点(切点),则此点在封闭图形外面;
;;;2,如果该直线与封闭图形有2个交点,且此点在这两个交点之间,则此点在封闭图形
;;;里面;在这两个交点之外,则此点在封闭图形外面;
;;;3,如果该直线与封闭图形有多个交点(不含切点),此点在这些交点之间时,此点
;;;任一侧的交点数为奇数则此点在封闭图形里面;此点任一侧的交点数为偶数则此点
;;;在封闭图形外面;此点不在这些交点之间时此点在封闭图形外面
动手写一个,效果好像还可以,如下
- ;;(MakeXray (setq p(getpoint)) '(0 1))
- ;;'(-1 0) 向左 '(0 1)向上 '(1 0)向右 '(0 -1)向下
- (defun MakeXray (p vector)
- (entmakeX
- (list
- '(0 . "RAY")
- '(100 . "AcDbEntity")
- '(100 . "AcDbRay")
- (cons 10 p)
- (cons 11 vector)
- )
- )
- )
- ;;偶数判断
- ;;(IsEven 2)=>T
- (defun IsEven (x)
- (/= 1 (logand x 1))
- )
- ;;向左产生一条射线ray
- ;; (setq ray (MakeXray p '(-1 0)))
- (defun HH_PtInCurve (p curve ray / A B FLAG IN L PTS)
- (setq Flag T)
- (setq in nil)
- (setq L '(((-1 0) (1 0)) ((0 1) (0 -1))))
- ;;射线移位
- (entmod (append (entget ray) (list (cons 10 p))))
- ;;旋转射线
- (while (and (setq a (car L)) Flag)
- (setq L (cdr L))
- (setq b (car a))
- (setq a (cadr a))
- (entmod (append (entget ray) (list (cons 11 b))))
- (setq pts (HH:TwoEntsInters ray curve 0))
- (cond ((not pts) (setq Flag nil))
- ((IsEven (length pts)) (setq Flag nil)) ;不严谨
- (T
- (entmod (append (entget ray) (list (cons 11 a))))
- (setq pts (HH:TwoEntsInters ray curve 0))
- (cond
- ((not pts) (setq Flag nil))
- ((IsEven (length pts)) (setq Flag nil)) ;不严谨
- (T (setq in T))
- )
- )
- )
- )
- in
- )
- ;;判断准则
- ;;1 如果所有端点首尾相连,则直接联接成多段线
- ;;2 如果只有一个端点是孤立的,则奇怪,可掉这条线
- ;;3 如果有两个端点孤立:是同一条线,奇怪,可去掉;如果是不同的线,可直接联接成多段线
- ;;4 如果大于两个端点孤立的,则相互延伸剪切,然后组成多段线。从一条线端点到另一条线最近的距离开始
- ;;0 [功能] 两对象交点
- ;;[功能] 两对象交点列表
- ;;acextendnone 0 不延伸
- ;;acextendthisentity 1 延伸基准对象
- ;;acextendotherentity 2
- ;;acextendboth 3
- ;;示例(HH:TwoEntsInters (car(entsel)) (car(entsel)) acextendboth)
- (defun HH:TwoEntsInters (e1 e2 Flag / PTL PTS)
- (if (equal 'ENAME (type e1))
- (setq e1 (vlax-ename->vla-object e1))
- )
- (if (equal 'ENAME (type e2))
- (setq e2 (vlax-ename->vla-object e2))
- )
- (setq pts (vlax-invoke e1 'Intersectwith e2 Flag))
- (while pts
- (setq ptl (cons (list (car pts) (cadr pts)) ptl))
- (setq pts (cdddr pts))
- )
- ptl
- )
;;;;;测试
(defun C:t1 (/ CURVE P RAY)
(setq ray (MakeXray '(0 0) '(-1 0)))
(setq curve (car (entsel "\n封闭曲线")))
(setq p (getpoint "\n点"))
(if (HH_PtInCurve p curve ray)
(alert "点在曲线内")
(alert "外")
)
(entdel ray)
(princ)
)
|