明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4563|回复: 14

如何判断一个点是否在平面凸多边形内?

  [复制链接]
发表于 2003-9-23 11:37:00 | 显示全部楼层 |阅读模式
参数是要判断的点及凸多边形各顶点坐标。
发表于 2003-9-23 14:47:00 | 显示全部楼层
适用于PLINE画的多边形
(defun GetNext (i n)
  (if (= i (1- n))
    0
    (1+ i)
  )
)

(defun c:test( / ss pt sname ent pt_tmp pt_lst vname area areaall)
  (setq ss (ssget))
  (setq pt (getpoint "Enter the point:"))
  (setq sname (ssname ss 0))
  (setq ent (entget sname))
  (while (setq pt_tmp (assoc 10 ent))
    (setq pt_lst (append pt_lst (list (cdr pt_tmp))))
    (setq ent (cdr (member pt_tmp ent)))
    (setq pts (append pts (list pt)))
  )
  (setq area 0)
  (setq i 0)
  (setq n (length pt_lst))
  (while (< i n)
    (entmake (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(67 . 0) '(410 . "Model") '(100 . "AcDbPolyline")
                   '(90 . 7) '(70 . 0) '(43 . 0.0) '(38 . 0.0) '(39 . 0.0)
                   (cons 10 pt)
                   '(40 . 0.0) '(41 . 0.0) '(42 . 0.0)
                   (cons 10 (nth i pt_lst))
                   '(40 . 0.0) '(41 . 0.0) '(42 . 0.0)
                   (cons 10 (nth (GetNext i n) pt_lst))
                   '(210 0.0 0.0 1.0))
             )
    (setq ent (entlast))
    (setq vname (vlax-ename->vla-object ent))
    (setq area (+ area (vla-get-area vname)))
    (entdel ent)
    (setq i (1+ i))
  )
  (setq areaall (vla-get-area (vlax-ename->vla-object sname)))
  (if (equal area areaall 0.000000001)
    (princ "\nin")
    (princ "\nout")
  )
  (princ)
)
 楼主| 发表于 2003-9-23 15:53:00 | 显示全部楼层
如果给出的顶点是按照顺序排列的,那么楼上的程序就能解决问题了。
另外楼上的程序没有考虑边界情况,要判断的点在边上的情况没考虑。
更进一步的问题是:任给n个点坐标(n>=3),如果能围合成平面凸多边形,那么就用line连接成平面凸多边形。
发表于 2003-9-23 16:13:00 | 显示全部楼层
如果在边界上,可以单独判断(这个很容易吧),
你的进一步问题好象没有提,我读来读去都没有象提问的样子,请问想做什么。

还有,我这个程序只是根据你提出的问题给出的一种方法,并不是一个最终可以使用的完善的程序,因为你只是提问如何做到,并没有要求写出完整的程序。你可以根据我的程序进一步完善或重写。
发表于 2003-9-26 15:23:00 | 显示全部楼层
;;; 9/4/03 - 6:36 AM 9/8/2003 by Luis Esquivel
;;; http://www.draftteam.com

(defun POINT-INSIDE-REGION-P
       (VLA_POLY PT AID-PT PTS / VLA_LINE LST_VALUE PARAM RESULT)
  (setq
    RESULT
     (cond
       ((and (setq PARAM (vlax-curve-getparamatpoint VLA_POLY PT))
             (eq (type (- PARAM (fix PARAM))) 'REAL)
        )
        NIL
       )
       ((and (not (vl-position (list (car PT) (cadr PT)) PTS))
             (not
               (vl-catch-all-error-p
                 (setq LST_VALUE
                        (vl-catch-all-apply
                          'vlax-safearray->list
                          (list        (vlax-variant-value
                                  (vla-intersectwith
                                    VLA_POLY
                                    (setq VLA_LINE
                                           (vla-addline
                                             (vla-objectidtoobject
                                               (vla-get-document VLA_POLY)
                                               (vla-get-ownerid VLA_POLY)
                                             )
                                             (vlax-3d-point PT)
                                             (vlax-3d-point AID-PT)
                                           )
                                    )
                                    acextendnone
                                  )
                                )
                          )
                        )
                 )
               )
             )
        )
        (fix (/ (length LST_VALUE) 3.0))
       )
     )
  )
  (vl-catch-all-apply 'vla-delete (list VLA_LINE))
  (if (numberp RESULT)
    (not (zerop (rem RESULT 2)))
  )
)

(defun C:TEST (/ ENT ELST PT VLA_POLY LC UC)
  (if
    (and (setq ENT (car (entsel "\nSelect a polyline: ")))
         (or (eq (cdadr (setq ELST (entget ENT))) "LWPOLYLINE")
             (eq (cdadr (setq ELST (entget ENT))) "OLYLINE")
         )
         (eq (vla-get-closed
               (setq VLA_POLY (vlax-ename->vla-object ENT))
             )
             :vlax-true
         )
         (setq PT (getpoint "\nTest point: "))
    )
     (progn
       (vla-getboundingbox VLA_POLY 'LC 'UC)
       (POINT-INSIDE-REGION-P
         VLA_POLY
         PT
         (polar        PT
                (/ pi 2.0)
                (distance (vlax-safearray->list LC)
                          (vlax-safearray->list UC)
                )
         )
         (mapcar
           'cdr
           (vl-remove-if-not
             (function (lambda (ITEM) (eq (car ITEM) 10)))
             ELST
           )
         )
       )
     )
  )
)
(princ)
发表于 2005-6-10 17:56:00 | 显示全部楼层
我也来一个,和龙版主的功能一样,同样适用行自相交多边形,但不适用于曲线。

本帖子中包含更多资源

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

x
发表于 2005-6-10 22:00:00 | 显示全部楼层
如果是凸多边形的话。。。。先不论效率,提出个思路,玩玩:)
  1. (defun c:tt ()
  2.    (arxload "geomcal")
  3.    (setq p (getpoint "\n 取点:")
  4.   el(entsel "\n 选择多义线:"))
  5.    (setq pts (mapcar 'cdr(vl-remove-if '(lambda(x)(/= 10 (car x))) (entget(car el)))))
  6.    (equal 360.0 (apply '+ (mapcar '(lambda(x y)(c:cal "ang(p,x,y)")) (cons (last pts) pts) pts)) 1e-4)
  7. )
主要判断语句: (equal 360.0 (apply '+ (mapcar '(lambda(x y)(c:cal "ang(p,x,y)")) (cons (last pts) pts) pts)) 1e-4)
发表于 2005-6-10 23:02:00 | 显示全部楼层
我的想法应该和无痕的一样,顺时针判断检测点与两个定点的走向,出现逆时针则点在外面,反之亦然。只是想法,没有测试也没有深思
发表于 2005-6-10 23:15:00 | 显示全部楼层
无痕兄的程序测试过吗?我测试出来不对。如果仅仅是凸多边形没有什么意义,应该适用于不规则多边形才好,最好可以适用于任何曲线(包括圆和椭圆)
发表于 2005-6-11 00:14:00 | 显示全部楼层
我贴出的只是个想法,而且如果不是凸多边形可能会错,前面已经说明.


如果用这个方法对付非凸边形,应该还用对夹角进行+-判断....那样似乎可行:)没时间写咯





适用于任何曲线(包括圆和椭圆)甚至spline的,我记得以前贴过了.这里就不重复了:)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-17 13:38 , Processed in 0.180913 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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