明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3780|回复: 8

判断一个对象是否在封闭曲线内

[复制链接]
发表于 2012-1-12 13:08:33 | 显示全部楼层 |阅读模式
本帖最后由 自贡黄明儒 于 2012-1-12 16:13 编辑

;;;作局部放大或者裁剪,都需要判断对象是否在封闭曲线内,今天正儿八经看了vla-intersectwith
;;;下的用法,发现两任何对象都可求交点,见笑了.
;;;判断一个对象是否在封闭曲线内(在曲线内返回T)
(defun C:In-or-out (/ OBJ1 OBJ2 P1 P2 UTIL)
  (vl-load-com)
  ;;1  以下对象是指除Pviewport和PolygonMesh外的任何对象
  ;;对象交点列表 or nil
  (defun All-intersectwith (obj1 obj2 / INT IPLIST)
    (setq int (vla-IntersectWith obj1 obj2 acExtendNoNe))
    (setq iplist (vl-catch-all-apply 'vlax-safearray->list (list (vlax-variant-value int))))
    (if (vl-catch-all-error-p iplist)
      nil
      (list->3pair iplist)
    )
  )                                                                                                                                                                                           ;defun
  ;;2  点在曲线内外,caoyin
  ;;  T------->在曲线内
  (defun LT:PT-INCURVE (PT CURVE / GetInters OBJ MINPT MAXPT E PS LST X Y)
    (defun GetInters (OBJ1 OBJ2 / PS LST)
      (setq PS (vla-intersectwith OBJ1 OBJ2 0)
            PS (vl-catch-all-apply 'vlax-safearray->list (list (vlax-variant-value PS)))
      )
      (if (and PS (not (vl-catch-all-error-p PS)))
        (while (setq LST (cons (list (car PS) (cadr PS)) LST)
                     PS  (cdddr PS)
               )
        )
      )
      LST
    )
    (if (equal (vlax-curve-getClosestPointTo CURVE PT) PT 1E-6)
      0
      (progn (setq OBJ (vlax-ename->vla-object CURVE))
             (vla-getboundingbox OBJ 'MINPT 'MAXPT)
             (mapcar '(lambda (X) (set X (vlax-safearray->list (eval X)))) '(MINPT MAXPT))
             (entmake
               (list '(0 . "LINE") (list 10 (car MINPT) (cadr PT)) (list 11 (car MAXPT) (cadr PT)) '(60 . 1))
             )
             (setq E    (entlast)
                   LST1 (GetInters OBJ (vlax-ename->vla-object E))
             )
             (entdel E)
             (if LST1
               (setq LST1 (vl-remove-if '(lambda (X / PP A)
                                           (setq PP (vlax-curve-getParamAtPoint CURVE X)
                                                 A  (angle '(0 0) (vlax-curve-getFirstDeriv CURVE PP))
                                           )
                                           (or (equal A 0 1E-6) (equal A PI 1E-6) (equal A (* PI 2) 1E-6) (equal (fix PP) PP 1E-6))
                                         )
                                        LST1
                          )
               )
             )
             (entmake
               (list '(0 . "LINE") (list 10 (car PT) (cadr MAXPT)) (list 11 (car PT) (cadr MINPT)) '(60 . 0))
             )
             (setq E    (entlast)
                   LST2 (GetInters OBJ (vlax-ename->vla-object E))
             )
             (entdel E)
             (if LST2
               (setq LST2 (vl-remove-if '(lambda (X / PP A)
                                           (setq X  (vlax-curve-getClosestPointTo CURVE X)
                                                 PP (vlax-curve-getParamAtPoint CURVE X)
                                                 A  (angle (vlax-curve-getFirstDeriv CURVE PP) '(0 0))
                                           )
                                           (or (equal A (/ PI 2) 1E-6) (equal A (* PI 1.5) 1E-6) (equal (fix PP) PP 1E-6))
                                         )
                                        LST2
                          )
               )
             )
             (and LST1
                  LST2
                  (progn (setq X (vl-sort-i (mapcar 'car (cons PT LST1)) '<)
                               Y (length (member 0 X))
                         )
                         (and (zerop (rem Y 2)) (= (rem (- (length X) Y) 2) 1))
                  )
                  (progn (setq X (vl-sort-i (mapcar 'cadr (cons PT LST2)) '<)
                               Y (length (member 0 X))
                         )
                         (and (zerop (rem Y 2)) (= (rem (- (length X) Y) 2) 1))
                  )
             )
      )
    )
  )

  
;;4  主程序
  (setq util (vla-get-utility (vla-get-activedocument (vlax-get-acad-object))))
  (vla-getentity util 'obj1 'ip "\n选择封闭曲线: ")
  (vla-getentity util 'obj2 'ip "\n选择对象: ")
  ;;如果两对象没有交点,要么在封闭曲线内,要么在封闭曲线外,故取对象中点判断是否在
  ;;封闭曲线内外即可
  (if (All-intersectwith obj1 obj2)
    nil
    (progn (vla-getboundingbox obj2 'p1 'p2)
           (setq p1 (vlax-safearray->list p1))
           (setq p2 (vlax-safearray->list p2))
           (LT:PT-INCURVE p1 (vlax-vla-object->ename obj1))
    )
  )
)

本帖子中包含更多资源

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

x
"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2012-1-12 15:41:04 | 显示全部楼层
我的论坛空间里面有一个更简单的思路,你可以参考下

点评

你的贴子我看过多次了,没有找到你说的更简单的  发表于 2012-1-12 15:48
好的,我看看。  发表于 2012-1-12 15:42
发表于 2012-1-12 16:15:50 | 显示全部楼层
;;(defun c:TT (/ EN pt typ dst)
(if (and (setq en (car (entsel)))
         (or (vlax-curve-isClosed en)
             (progn(princ"\n曲线未封闭")nil)
         )
         (setq pt (getpoint"\n拾取点: "))
    )
(progn
  (setq typ (cdr (assoc 0 (entget en)))
        dst (lt:curve-getDistancePtTo En PT)
  )
  (if (wcmatch typ "*POLYLINE")
    (setq dst (- DST))
  )
  (cond ((> dst 0)(alert "点在曲线内"))
        ((= dst 0)(alert "点在曲线上"))
        ((< dst 0)(alert "点在曲线外"))
  )
)
)
)
发表于 2012-1-12 16:45:51 | 显示全部楼层
本帖最后由 byghbcx 于 2012-1-13 08:28 编辑

可以通过过已知点与曲线最近的点所构成的直线与曲线的交点个数关于这个点的两边对称关系来判断。
(defun c:TT (/ EN pt pt1 en1 intpnt tmppnt ang k)
(if (and (setq en (car (entsel)))
         (or (vlax-curve-isClosed en)
             (progn(princ"\n曲线未封闭")nil)
         )
         (setq pt (getpoint"\n拾取点: "))
    )
(progn
  (setq pt1 (vlax-curve-getClosestPointTo en pt))
  (command "_.line" pt pt1 "")
  (setq en1 (entlast))
  (setq INTPNT (vla-intersectwith (vlax-ename->vla-object en1) (vlax-ename->vla-object en) acextendThisEntity)
        TMPPNT (vlax-variant-value INTPNT)
  )
  (cond ((safearray-value TMPPNT)
        (setq TMPLST (vlax-safearray->list TMPPNT))
        (repeat        (/ (length TMPLST) 3)
          (setq        PNTLST  (cons (list (car TMPLST) (cadr TMPLST) (caddr TMPLST)) PNTLST)
                TMPLST (cdddr TMPLST)
          )
        )
        (reverse PNTLST)
       )
       (t NIL)
  )
  (command "_.erase" en1 "")
  (setq ang (angle pt pt1) k 1)
  (mapcar '(lambda(x) (setq k (* k (if (equal (angle pt x) ang 0.0001) 1 -1)))) PNTLST)
  (cond ((= k -1)(alert "点在曲线内"))
        ((= k 1)(alert "点在曲线外"))
  )
)
)
)

点评

可以运行,不过点在线上的时候没有提示,改进一下就更好了。  发表于 2015-9-10 22:42
很容易理解,不错的思路  发表于 2012-1-13 10:39
发表于 2012-1-13 17:02:57 | 显示全部楼层
学习一下方法。
发表于 2012-1-13 18:20:59 | 显示全部楼层
求以上大师编写出放大样LISP,谢谢!
发表于 2012-3-15 00:47:57 | 显示全部楼层
多谢楼主分享,收藏学习了
发表于 2015-9-10 22:40:32 | 显示全部楼层
caoyin 发表于 2012-1-12 16:15
;;(defun c:TT (/ EN pt typ dst)
(if (and (setq en (car (entsel)))
         (or (vlax-curve-isClose ...

命令: tt

选择对象:
拾取点: ; 错误: no function definition: LT:CURVE-GETDISTANCEPTTO

命令:
命令: !dst nil

命令: !typ nil

命令: !pt nil
运行不正确?
发表于 2019-12-14 23:32:46 | 显示全部楼层
如果一个实体其中的一部分刚好在另一个实体的线上,会返回不在实体内
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-5-18 10:53 , Processed in 0.300185 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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