天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 59|回复: 0

[函数] 判断点在封闭曲线内,跟随黄总的步伐

[复制链接]
  • TA的每日心情
    开心
    5 天前
  • 签到天数: 49 天

    [LV.5]常住居民I

    185

    主题

    150

    回帖

    1695

    积分

    管理员

    积分
    1695
    发表于 2024-4-4 08:35:51 | 显示全部楼层 |阅读模式


    1. ;测试
    2. (defun c:tt (/ en pt pts)
    3.         (and
    4.                 (setq pt (getpoint))
    5.                 (setq en (car (entsel "\n选闭合曲线")))
    6.                 (setq pts (mapcar '(lambda (x) (trans (cdr x) 0 1)) (vl-remove-if-not '(lambda (x) (= 10 (car x))) (entget en))))
    7.                 (princ "\n第一种(不支持弧线):")
    8.                 (princ (JudPtinPts pt pts 1e-6))
    9.                 (princ "\n第二种(支持弧线):")
    10.                 (princ (JudPtinCurr pt en 1e-6))
    11.         )
    12.         (princ)
    13. )








    14. ;第一种
    15. ;判断点是否在非自交多边形内,使用射线交叉法,从要测试的点向任意方向引一条射线,统计射线与多边形边界的交点数量。如果交点数目是奇数,则点位于多边形内部;如果是偶数,则点位于多边形外部。如果交点为多边形顶点可能无法正确判断,此时旋转射线重新判断。
    16. ;参数:pt判断的点、pts多边形点表、fz误差
    17. ;返回:1在内部、0在线上、-1在外部
    18. (defun JudPtinPts (pt pts fz / box d i inter k line lines lines-tmp memberfz ray)
    19.   (defun MemberFz (pt lst fz);带误差的member
    20.     (vl-some (function (lambda(x) (equal pt x fz))) lst)
    21.   )
    22.   
    23.   (setq lines (mapcar (function list) pts (append (cdr pts) (list (car pts)))))
    24.   (if (vl-some ;判断点在线上
    25.         (function (lambda (x / ang1 ang2 p1 p2)
    26.                     (setq p1 (car x))
    27.                     (setq p2 (cadr x))
    28.                     (or
    29.                       (or
    30.                         (equal pt p1 fz)
    31.                         (equal pt p2 fz)
    32.                       )
    33.                       (and
    34.                         (setq ang1 (angle p1 pt))
    35.                         (setq ang2 (angle pt p2))
    36.                         (or (equal ang1 ang2 1e-6)
    37.                           (equal (abs (- ang1 ang2)) (* pi 2) 1e-6)
    38.                         )
    39.                       )
    40.                     )
    41.                   )
    42.         )
    43.         lines
    44.       )
    45.     0;在线上
    46.     (progn;判断交点数量
    47.       (setq box (mapcar (function (lambda (a b) (apply (function mapcar) (cons a b)))) '(min max) (list pts pts)))
    48.       (setq d (+ (apply 'distance box) (distance pt (car pts))))
    49.       (setq ray (list pt (polar pt 0 d)));虚拟一条足够长的射线
    50.       (setq lines-tmp lines)
    51.       (setq i 0 k 0)
    52.       (while (and lines-tmp (< k 360))
    53.         (setq line (car lines-tmp))
    54.         (setq lines-tmp (cdr lines-tmp))
    55.         (if (setq inter (apply 'inters (append ray line)));有交点
    56.           (if (not (MemberFz inter pts fz));且交点不为顶点
    57.             (setq i (1+ i));交点数量
    58.             (setq i 0;归零
    59.               k (1+ k)
    60.               ray (list pt (polar pt (* (/ pi 180) k) d));射线旋转1°
    61.               lines-tmp lines;重新判断
    62.             )
    63.           )
    64.         )
    65.       )
    66.       (cond
    67.         ((zerop (rem i 2)) -1);偶数个交点,在线外
    68.         (t 1);奇数,在线内
    69.       )
    70.     )
    71.   )
    72. )














    73. ;第二种
    74. ;判断点是否在封闭曲线内,生成图元射线找与封闭曲线交点(判断原理同上),支持多段线、圆、椭圆、样条曲线等封闭曲线
    75. ;参数:pt判断的点、e曲线图元名、fz误差
    76. ;返回:1在内部、0在线上、-1在外部
    77. (defun JudPtinCurr (pt e fz / *error* ang cp ed getinter i islock isvertex its k la layobj list->3pair loop mkray obj-cur obj-ray ray vlay)
    78.   ;错误处理
    79.   (defun *error* (msg)
    80.     (if (not (vlax-erased-p obj-ray))
    81.       (vla-Delete obj-ray)
    82.     )
    83.     (princ msg)
    84.   )
    85.   ;表转3D点表
    86.   (defun list->3pair (old / new)
    87.     (while (setq new (cons (list (car old) (cadr old) (caddr old)) new) old (cdddr old)))
    88.     (reverse new)
    89.   )
    90.   ;找2个对象的交点 不延长 返回:交点列表
    91.   (defun getinter (obj1 obj2 / inter iplist re)
    92.     (if (not (vl-catch-all-error-p
    93.                (setq iplist (vl-catch-all-apply 'vlax-safearray->list
    94.                               (list (vlax-variant-value (vla-intersectwith obj1 obj2 acextendnone)))
    95.                             ))))
    96.       (list->3pair iplist)
    97.     )
    98.   )
    99.   ;判断交点是否为曲线顶点或在射线角度上的切点
    100.   (defun IsVertex (obj pt ang / ang-de de n name)
    101.     (if (and
    102.           (setq name (vla-get-ObjectName obj))
    103.           (setq n (vlax-curve-getParamAtPoint obj pt))
    104.         )
    105.       (if (and
    106.             (or
    107.               (= name "AcDbPolyline")
    108.               (= name "AcDb2dPolyline")
    109.               (= name "AcDb3dPolyline")
    110.               (= name "AcDbSpline")
    111.             )
    112.             (equal (fix n) n 1e-8)
    113.           )
    114.         t ;为顶点
    115.         (and ang
    116.           (setq de (vlax-curve-getFirstDeriv obj n))
    117.           (setq ang-de (angle '(0 0 0) de))
    118.           (or ;为切点
    119.             (equal ang-de ang 1e-8)
    120.             (equal ang-de (+ pi ang) 1e-8)
    121.             (equal ang-de (+ (* pi 2) ang) 1e-8)
    122.           )
    123.         )
    124.       )
    125.     )
    126.   )
    127.   ;生成射线 返回图元名
    128.   (defun MKRay (p1 p2)
    129.     (entmakeX
    130.       (list
    131.         '(0 . "RAY")
    132.         '(100 . "AcDbEntity")
    133.         '(100 . "AcDbRay")
    134.         (cons 10 p1)
    135.         (cons 11 (mapcar '- p2 p1))
    136.       )
    137.     )
    138.   )
    139.   
    140.   (setq obj-cur (vlax-ename->vla-object e))
    141.   (if (and
    142.         (setq cp (vlax-curve-getClosestPointTo obj-cur pt))
    143.         (equal cp pt fz)
    144.       )
    145.     0;在线上
    146.     (progn
    147.       (if (and ;解锁当前图层
    148.             (setq la (getvar "CLAYER"))
    149.             (setq layobj (vla-get-Layers (vla-get-activedocument (vlax-get-acad-object))))
    150.             (setq vlay (vla-item layobj la))
    151.           )
    152.         (if (= (vla-get-lock vlay) :vlax-true)
    153.           (progn
    154.             (vla-put-lock vlay :vlax-false)
    155.             (setq islock t)
    156.           )
    157.         )
    158.       )
    159.       (setq ang 0)
    160.       (setq pt (trans pt 1 0))
    161.       (setq ray (MKRay pt (polar pt ang 10)))
    162.       (setq ed (entget ray))
    163.       (setq obj-ray (vlax-ename->vla-object ray))
    164.       (setq k 0 loop t)
    165.       (while (and loop (< k 360))
    166.         (if (setq its (getinter obj-cur obj-ray));有交点
    167.           (progn
    168.             (if (vl-every (function (lambda(p) (not (IsVertex obj-cur p ang)))) its)
    169.               (setq i (length its);交点数量
    170.                 loop nil
    171.               )
    172.               (progn;交点为顶点或切点
    173.                 (setq k (1+ k) ang (* (/ pi 180) k))
    174.                 (entmod (subst (cons 11 (mapcar '- (polar pt ang 10) pt)) (assoc 11 ed) ed));射线旋转1°
    175.               )
    176.             )
    177.           )
    178.           (setq loop nil)
    179.         )
    180.       )
    181.       (if (not (vlax-erased-p obj-ray))
    182.         (vla-Delete obj-ray)
    183.       )
    184.       (if islock ;恢复锁定
    185.         (vla-put-lock vlay :vlax-true)
    186.       )
    187.       (cond
    188.         ((or (not i)(zerop (rem i 2))) -1);偶数个交点,在线外
    189.         (t 1);奇数,在线内
    190.       )
    191.     )
    192.   )
    193. )

    复制代码

     

     

     

     

    [函数] 判断点在封闭曲线内,跟随黄总的步伐
    哎...膜结构车棚,签到来了1...
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|中国膜结构网_中国空间膜结构协会

    GMT+8, 2024-5-16 07:12 , Processed in 0.057792 second(s), 21 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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