明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2539|回复: 9

请教如何判断某一点是否在已知的面域内?

[复制链接]
发表于 2005-3-23 14:18:00 | 显示全部楼层 |阅读模式
如果已知的面域是规则的图形,例如圆形或矩形,则判断的方法不难!但如果已知的面域是不规则的图形,(如下图)这时候又怎样判断?有没有通用的方法?谢了!
发表于 2005-3-23 14:52:00 | 显示全部楼层
我也想知道怎么判断一个对象在某一区域内,你要是知道告诉我,谢谢


Email:tsdry@126.com
发表于 2005-3-23 23:03:00 | 显示全部楼层
1、检查点是否在区域边界上,这种情况你自己看着办。


2、如果不在边界上,以这一点画一射线,检查它与区域边界相交的次数。奇数次的在区域内部。


至于如何实现,就有点麻烦了。


以封闭多段线作为区域边界为例子说一下:


第1步:可以用曲线函数vlax-curve-getClosestPointTo实现,返回值与点的距离达到某种精度时(比如说0.000001),就认为这是线上的点。


第2步:使用GetBoundingBox 方法找出边界的坐标范围,从点连接一条线到区域边界的最大坐标,检查相交次数,确认点是否在区域范围内。
发表于 2005-3-24 00:19:00 | 显示全部楼层
画一个小圆圈,做成面域,求并,看看面积是否增加
发表于 2005-3-24 08:25:00 | 显示全部楼层
这招好使, 鲜花奖励
发表于 2005-3-24 09:34:00 | 显示全部楼层
BDYCAD发表于2005-3-24 8:25:00这招好使, 鲜花奖励

以前给你做的某个程序里我就用了这个的,数量大的时候慢得要死
发表于 2005-3-26 21:56:00 | 显示全部楼层
(defun hy_inorout(point en / base_area);;;判断点是否在封闭图形内 pt="in" pt="out"
(command "area" "o" en)
(setq base_area (getvar "area"))
(command "offset" 0.01 en point "")
(command "area" "o" (entlast))
(command "erase" (entlast) "")
(if (< (getvar "area") base_area) (setq pt "in") (setq pt "out"))
) 参考一下我编的这个程序吧,如果你是一个面域的话,可以再编一个程序穿插在前面 先让面域变为封闭图元,在调用此程序,然后在加一个(COMMAN "REGION" (ENTLAST) "")使他还是回复为面域就可以拉!
发表于 2005-3-28 11:55:00 | 显示全部楼层
检查函数
  1. ;;;检查点是否落在指定坐标范围内
  2. ;;;参数说明
  3. ;;;  pts  坐标列表
  4. ;;;  pt_test  检查坐标
  5. ;;;返回值说明:
  6. ;;;  -1  在区域边界上
  7. ;;;  0  在区域外部
  8. ;;;  1  在区域内部
  9. (DEFUN check_pt_on_area  (pts pt_test / check_pre count_inter on_line pt  pt_inter pt_last pt_max)
  10.    (SETQ  check_pre     1e-7         ;设置检查精度,用于EQUAL
  11.   ;;去掉考虑Z坐标
  12.   pts         (MAPCAR '(LAMBDA (pt) (LIST (CAR pt) (CADR pt))) pts)
  13.   pt_test         (LIST (CAR pt_test) (CADR pt_test))
  14.   ;;得到最大坐标
  15.   pt_max         (LIST (APPLY 'MAX (MAPCAR 'CAR pts))
  16.          (APPLY 'MAX (MAPCAR 'CADR pts))
  17.            )
  18.   pt_last         (LAST pts)
  19.   ;;相交次数
  20.   count_inter 0
  21.   on_line         nil
  22.    )
  23.    ;;检查相交次数
  24.    (WHILE pts
  25.        (IF  (SETQ pt_inter (INTERS pt_max pt_test (CAR pts) pt_last T))
  26.            (PROGN (SETQ count_inter (1+ count_inter))
  27.            (IF (EQUAL pt_inter pt_test check_pre)
  28.                (SETQ on_line T)
  29.            )
  30.            )
  31.        )
  32.        (SETQ pt_last (CAR pts)
  33.      pts     (CDR pts)
  34.        )
  35.    )
  36.    ;;如果是返回状态值
  37.    (IF on_line
  38.        -1
  39.        (REM count_inter 2)
  40.    )
  41. )
复制代码
测试函数
  1. ;;;以下部分为测试定义的  ;;;测试函数
  2. (DEFUN c:test (/ ent pt result)
  3.    (IF (SETQ ent (SSGET ":s" '((0 . "*POLYLINE"))))
  4.        (IF  (SETQ pt (GETPOINT "\n指定检测点:"))
  5.            (PROGN (SETQ result (check_pt_on_area (CAR (get_points (SSNAME ent 0))) pt))
  6.            (ALERT (STRCAT "指定点在"
  7.              (COND ((= result -1) "边界上!")
  8.            ((= result 0) "外部。")
  9.            ((= result 1) "内部。")
  10.              )
  11.            )
  12.            )
  13.            )
  14.        )
  15.    )
  16.    (PRINC)
  17. );;;得到LWPOLYLINE,POLYLINE,LINE,TEXT的点表和最大点/最小点
  18. ;;;进入  对象名
  19. ;;;返回  ( (点表) (最大点) (最小点) )
  20. (DEFUN get_points (ent_name / ent_data points ent_type max_zb min_zb x)
  21.    (SETQ ent_data (ENTGET ent_name))
  22.    (SETQ ent_type (CDR (ASSOC '0 ent_data)))
  23.    (SETQ points (LIST))
  24.    (COND  ((= ent_type "LINE")
  25.    (SETQ points (LIST (CDR (ASSOC 10 ent_data)) (CDR (ASSOC '11 ent_data))))
  26.   )
  27.   ((= ent_type "POLYLINE")
  28.    ;;闭合线最后加上第一点
  29.    (IF (= 1 (REM (CDR (ASSOC '70 ent_data)) 2))
  30.        (SETQ max_zb T)
  31.        (SETQ max_zb nil)
  32.    )
  33.    (WHILE  (/= ent_type "SEQEND")
  34.        (SETQ ent_name (ENTNEXT ent_name))
  35.        (SETQ ent_data (ENTGET ent_name))
  36.        (SETQ ent_type (CDR (ASSOC '0 ent_data)))
  37.        (IF (= ent_type "VERTEX")
  38.            (IF (OR (= '0 (CDR (ASSOC '70 ent_data)))
  39.              (= '16 (CDR (ASSOC '70 ent_data)))
  40.      )
  41.                (SETQ points (APPEND points (LIST (CDR (ASSOC '10 ent_data)))))
  42.            )
  43.        )
  44.    )
  45.    (IF max_zb
  46.        (SETQ points (APPEND points (LIST (NTH 0 points))))
  47.    )
  48.   )
  49.   ((= ent_type "LWPOLYLINE")
  50.    ;;闭合线最后加上第一点
  51.    (IF (= 1 (REM (CDR (ASSOC '70 ent_data)) 2))
  52.        (SETQ max_zb T)
  53.        (SETQ max_zb nil)
  54.    )
  55.    (FOREACH one ent_data
  56.        (IF (= (CAR one) 10)
  57.            (SETQ points (APPEND points (LIST (CDR one))))
  58.        )
  59.    )
  60.    (IF max_zb
  61.        (SETQ points (APPEND points (LIST (NTH 0 points))))
  62.    )
  63.   )
  64.   ((= ent_type "HATCH")
  65.    (FOREACH one ent_data
  66.        (IF (= (CAR one) 10)
  67.            (SETQ points (APPEND points (LIST (CDR one))))
  68.        )
  69.    )
  70.   )
  71.   ((= ent_type "CIRCLE")
  72.    (SETQ points (LIST (CDR (ASSOC 10 ent_data))))
  73.   )
  74.   ((= ent_type "POINT")
  75.    (SETQ points (LIST (CDR (ASSOC 10 ent_data))))
  76.   )
  77.   ((= ent_type "TEXT")
  78.    (SETQ points (LIST (CDR (ASSOC 10 ent_data))))
  79.   )
  80.   ((= ent_type "MTEXT")
  81.    (SETQ points (LIST (CDR (ASSOC 10 ent_data))))
  82.   )
  83.   ((= ent_type "INSERT")
  84.    (SETQ points (LIST (CDR (ASSOC 10 ent_data))))
  85.   )
  86.   ((= ent_type "IMAGE")
  87.    (SETQ points (LIST (CDR (ASSOC 10 ent_data))))
  88.   )
  89.   (T
  90.    (ALERT
  91.        (STRCAT "错误:\n\t出现没有处理的对象类型< " ent_type ">。")
  92.    )
  93.    (EXIT)
  94.   )
  95.    )               ;去掉Z坐标
  96.    (MAPCAR '(LAMBDA (x) (LIST (NTH 0 x) (NTH 1 x))) points) ;求最大值/最小值
  97.    (SETQ max_zb (CAR points))
  98.    (SETQ min_zb (CAR points))
  99.    (MAPCAR '(LAMBDA (x)
  100.            (SETQ max_zb (MAPCAR 'MAX max_zb x))
  101.            (SETQ min_zb (MAPCAR 'MIN min_zb x))
  102.        )
  103.      points
  104.    )
  105.    (SETQ ent_data (LIST points max_zb min_zb))
  106. )
复制代码
发表于 2005-3-28 16:29:00 | 显示全部楼层
lockmyeye,的程序,对于矩形就会出错了。
发表于 2005-3-28 17:35:00 | 显示全部楼层
舟自横发表于2005-3-26 21:56:00(defun hy_inorout(point en / base_area);;;判断点是否在封闭图形内 pt=\"in\" pt=\"out\"   (command \"area\" \"o\" en)   (setq base_area (getvar \"area\"))
  1. 还是觉得此法有用,如果用面域合并的话,圆的大小不好把握。
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-9-29 06:32 , Processed in 0.194835 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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