找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2956|回复: 13

[研讨] 判断点在封闭曲线内外,自交曲线不适用-----希望适合UCS

[复制链接]

已领礼包: 604个

财富等级: 财运亨通

发表于 2014-11-20 16:54:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

×
本人改编G版的程序,希望适合ucs,也不知改对没有,大家帮看看。
highflybir大师的那个程序大复杂,使用不便
  1. ;;164.42 [功能] 判断点在封闭曲线内外,自交曲线不适用-----希望适合UCS
  2. ;;根据Gu_xl程序改编,希望适合UCS-----自贡黄明儒 2014.11.20
  3. ;;返回: 点在封闭曲线上或曲线内,返回T,否则返回nil
  4. ;;测试: (HH:PtInCurveP  (car(entsel "\n选择曲线:")) (getpoint))
  5. (defun HH:PtInCurveP (POLY PT / CLOCKWISEP CP CURVELENGTH D1 D2 DEV DIST ENDPARAM ISUCS LST LW MAXP MINP PARAM X)
  6.   (setq IsUCS (= (getvar "WORLDUCS") 0))
  7.   (cond (IsUCS (setq pt (trans pt 1 0))))
  8.   (setq cp (vlax-curve-getclosestpointto poly pt))
  9.   (cond
  10.     ((equal pt cp 1e-8) T) ;_ 点在曲线上 T
  11.     ((progn
  12.        (setq lw (vlax-ename->vla-object POLY))
  13.        (vla-GetBoundingBox lw 'MinP 'MaxP)
  14.        (setq MinP (vlax-safearray->list MinP))
  15.        (setq MaxP (vlax-safearray->list MaxP))
  16.        (not (ALG:InCorner-p pt MinP MaxP))
  17.      )
  18.      NIL ;_ 点在曲线最小包围盒外 nil
  19.     )
  20.     (t
  21.      (setq lst (_pnts:box (list MinP MaxP)))                    ;4角点
  22.      (setq
  23.        lst (mapcar
  24.              '(lambda (x)
  25.                 (vlax-curve-getParamAtPoint
  26.                   lw
  27.                   (vlax-curve-getClosestPointTo lw x)
  28.                 )
  29.               )
  30.              lst
  31.            )
  32.      ) ;_ 最小包围盒点在曲线上的投影点的参数表
  33.      (setq ClockwiseP
  34.             (or
  35.               (<= (car lst) (cadr lst) (caddr lst) (cadddr lst))
  36.               (<= (cadr lst) (caddr lst) (cadddr lst) (car lst))
  37.               (<= (caddr lst) (cadddr lst) (car lst) (cadr lst))
  38.               (<= (cadddr lst) (car lst) (cadr lst) (caddr lst))
  39.             )
  40.      ) ;_ 判断曲线是否为顺时针,顺时针 = T
  41.      (setq endparam (vlax-curve-getendparam poly))
  42.      (setq curvelength (vlax-curve-getDistAtParam poly endparam)) ;_ 曲线长度
  43.      (setq param (vlax-curve-getparamatpoint poly cp))
  44.      (setq dist (vlax-curve-getDistAtParam poly param))
  45.      (if (equal param (fix param) 1e-8)
  46.        (progn
  47.          (cond ((minusp (setq d1 (- dist 1e-8))) (setq d1 (+ curvelength d1))))
  48.          (cond ((> (setq d2 (+ dist 1e-8)) curvelength) (setq d2 (- d2 curvelength))))
  49.          (setq d1 (vlax-curve-getpointatdist poly d1))
  50.          (setq d2 (vlax-curve-getpointatdist poly d2))
  51.          (if (<        (distance pt d1)
  52.                 (distance pt d2)
  53.              )
  54.            (setq param d1)
  55.            (setq param d2)
  56.          )
  57.        )
  58.      )
  59.      (setq dev (vlax-curve-getFirstDeriv poly param)
  60.            cp  (vlax-curve-getpointatparam poly param)
  61.      )     
  62.      (= ClockwiseP (minusp (det pt cp (mapcar '+ cp dev))))
  63.     )
  64.   )
  65. )


  66. ;; 判断点是否在窗口内  by highflybir
  67. (defun ALG:InCorner-p (pt pMin pMax)
  68.   (and
  69.     (<= (car pMin) (car pt) (car pMax))
  70.     (<= (cadr pMin) (cadr pt) (cadr pMax))
  71.   )
  72. )
  73. ;;[功能] 两角点变四点(左下 右下 右上 左上)
  74. (defun _pnts:box (box)
  75.   (list        (car box)
  76.         (list (caar box) (cadadr box) (last (car box)))
  77.         (cadr box)
  78.         (list (caadr box) (cadar box) (last (car box)))
  79.   )
  80. )
  81. ;;174.2 [功能] 叉积(外积) By Highflybird
  82. ;;1 三角形之倍面积
  83. ;;2 p1 p2 p3 逆时针为正。
  84. ;;3 三点共线为0
  85. (defun det (p1 p2 p3 / x2 y2)
  86.   (setq        x2 (car p2)
  87.         y2 (cadr p2)
  88.   )
  89.   (- (* (- x2 (car p3)) (- y2 (cadr p1))) (* (- x2 (car p1)) (- y2 (cadr p3))))
  90. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 1268个

财富等级: 财源广进

发表于 2014-11-21 07:58:01 | 显示全部楼层
本帖最后由 st788796 于 2014-11-21 08:06 编辑

黄老这个算法很巧妙,避免了以前的抽样点方法可能出现的误差,肯定花了不少功夫,给大家讲讲具体算法吧

不过首先要判断是否封闭,开放曲线就没有内外了

在 Arx 的 Brep 类中,将曲线构造一个 Brep (Region)就可以使用 getPointRelationToBrep 函数,返回 kInside、kOutside、kCoincident 等,也就是 xdrx_point_getRelationAtClosedCurve  方法,在ARX中构造 Brep 不需要实体添加到数据库的

点评

这个G版的呀,我只是希望用于UCS,其实只改了一句。(cond ((= (getvar "WORLDUCS") 0) (setq pt (trans pt 1 0))))  详情 回复 发表于 2014-11-21 08:02
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 604个

财富等级: 财运亨通

 楼主| 发表于 2014-11-21 08:02:35 | 显示全部楼层
st788796 发表于 2014-11-21 07:58
黄老这个算法很巧妙,避免了以前的抽样点方法可能出现的误差,肯定花了不少功夫,给大家讲讲具体算法吧

这个G版的呀,我只是希望用于UCS,其实只改了一句。(cond ((= (getvar "WORLDUCS") 0) (setq pt (trans pt 1 0))))

点评

增加此判断完全是画蛇添足,因为使用者调用此函数时明确知道pt是wcs还是ucs,你增加此判断判断出当前坐标系是ucs,也不能代表pt 坐标一定是ucs坐标!  详情 回复 发表于 2014-11-21 18:34
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

发表于 2014-11-21 08:08:59 | 显示全部楼层
本帖最后由 st788796 于 2014-11-22 08:59 编辑
/db_自贡黄明儒_ 发表于 2014-11-21 08:02
这个G版的呀,我只是希望用于UCS,其实只改了一句。(cond ((= (getvar "WORLDUCS") 0) (setq pt (trans p ...

vlax-curve 求出的都是 wcs , 对测试点直接 (trans pt 1 0) 不用判断
整理出几个基本函数
  1. (defun _pnts:box (box)
  2.   (list        (car box)
  3.         (list (caar box) (cadadr box) (last (car box)))
  4.         (cadr box)
  5.         (list (caadr box) (cadar box) (last (car box)))
  6.   )
  7. )
  8. (defun Curve:IsClosed (curve /)
  9.   (or (vlax-curve-isclosed curve)
  10.       (equal (vlax-curve-getstartpoint curve)
  11.              (vlax-curve-getendpoint curve)
  12.              1e-8
  13.       )
  14.   )
  15. )
  16. (defun Obj:Corner (ent / bp up)
  17.   (vla-getboundingbox ent 'bp 'up)
  18.   (list (safearray-value bp) (safearray-value up))
  19. )
  20. (defun Curve:Direction (curve / box params)
  21.   (setq        box    (_pnts:box (Obj:Corner curve))
  22.         params (mapcar
  23.                  '(lambda (x)
  24.                     (vlax-curve-getParamAtPoint
  25.                       curve
  26.                       (vlax-curve-getClosestPointTo curve x)
  27.                     )
  28.                   )
  29.                  box
  30.                )
  31.   )
  32.   (or
  33.     (apply '<= params)
  34.     (<= (cadr lst) (caddr params) (cadddr params) (car params))
  35.     (<=        (caddr params)
  36.         (cadddr params)
  37.         (car params)
  38.         (cadr params)
  39.     )
  40.     (<=        (cadddr params)
  41.         (car params)
  42.         (cadr params)
  43.         (caddr params)
  44.     )
  45.   )
  46. )

点评

你这么一搞,G版的东西看起来就短了,现代的人都喜欢长的,有故事为证,要不要我讲给你听?  详情 回复 发表于 2014-11-22 12:54

评分

参与人数 1D豆 +5 收起 理由
/db_自贡黄明儒_ + 5 很给力!经验;技术要点;资料分享奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2014-11-21 10:09:07 | 显示全部楼层
本帖最后由 zhxatsx 于 2014-11-21 10:19 编辑

;;试试这个,只适用ucs,需要其他条件可变改
;;判断点是否在封闭曲线内部
(defun iop (/ e1 e2 p rp pint pn)
  (setq e1 (vlax-ename->vla-object (car (entsel "请选择封闭曲线:"))))
  (setq p (getpoint "P: "))
  (setq        rp (entmakex (list '(0 . "ray")
                           '(100 . "AcDbEntity")
                           '(100 . "AcDbRay")
                           (cons 10 p)
                           '(11 1 0)
                     )
           )
  )
  (setq e2 (vlax-ename->vla-object rp))
  (setq pint (vlax-invoke e1 'intersectwith e2 0))
  (vlax-invoke-method e2 'delete)
  (setq pint (pm-ps pint))
  (cond
    ((member p pint) (prompt "\n此点在封闭曲线上"))
    ((and (setq pn (length pint)) (zerop (rem pn 2)))
     (prompt "\n此点在封闭曲线外部")
    )
    (t (prompt "\n此点在封闭曲线内部"))
  )
  (princ)
)

(defun Pm-Ps (pm / i)
  (setq        i  0
        ps '()
  )
  (repeat (/ (length pm) 3)
    (setq ps (cons (list (nth i pm) (nth (1+ i) pm) (nth (+ i 2) pm)) ps)
          i  (+ i 3)
    )
  )
  (setq ps (reverse ps))
)

点评

rp应该是e2,很早以前,就用射线法了。同样是适用于非自交多边形吧。但是如果有凹弧,也可能是3个交点的。  详情 回复 发表于 2014-11-21 10:18
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 604个

财富等级: 财运亨通

 楼主| 发表于 2014-11-21 10:18:47 | 显示全部楼层
本帖最后由 /db_自贡黄明儒_ 于 2014-11-21 10:21 编辑
zhxatsx 发表于 2014-11-21 10:09
;;试试这个
;;判断点是否在封闭曲线内部
(defun iop (/ e1 e2 p rp pint pn)

rp应该是e2,很早以前,就用射线法了。同样是适用于非自交多边形吧。但是如果有凹弧,也可能是3个交点的。
3.png
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 344个

财富等级: 日进斗金

发表于 2014-11-21 18:34:17 来自手机 | 显示全部楼层
/db_自贡黄明儒_ 发表于 2014-11-21 08:02
这个G版的呀,我只是希望用于UCS,其实只改了一句。(cond ((= (getvar "WORLDUCS") 0) (setq pt (trans p ...

增加此判断完全是画蛇添足,因为使用者调用此函数时明确知道pt是wcs还是ucs,你增加此判断判断出当前坐标系是ucs,也不能代表pt 坐标一定是ucs坐标!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 604个

财富等级: 财运亨通

 楼主| 发表于 2014-11-22 12:54:24 | 显示全部楼层
st788796 发表于 2014-11-21 08:08
vlax-curve 求出的都是 wcs , 对测试点直接 (trans pt 1 0) 不用判断
整理出几个基本函数

你这么一搞,G版的东西看起来就短了,现代的人都喜欢长的,有故事为证,要不要我讲给你听{:soso_e112:}?

点评

难道古代人喜欢短的?  详情 回复 发表于 2014-11-22 13:04
有故事就讲讲吗,洗耳恭听  详情 回复 发表于 2014-11-22 13:00
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 264个

财富等级: 日进斗金

发表于 2014-11-22 13:00:18 来自手机 | 显示全部楼层
/db_自贡黄明儒_ 发表于 2014-11-22 12:54
你这么一搞,G版的东西看起来就短了,现代的人都喜欢长的,有故事为证,要不要我讲给你听?
...

有故事就讲讲吗,洗耳恭听
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2014-11-22 13:04:03 | 显示全部楼层
/db_自贡黄明儒_ 发表于 2014-11-22 12:54
你这么一搞,G版的东西看起来就短了,现代的人都喜欢长的,有故事为证,要不要我讲给你听?
...

难道古代人喜欢短的?{:soso_e120:}
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 604个

财富等级: 财运亨通

 楼主| 发表于 2014-11-22 13:24:50 | 显示全部楼层
本帖最后由 /db_自贡黄明儒_ 于 2014-11-22 13:29 编辑

iLisp喜欢听,我就讲讲,如果被版主封贴了,你要负责任{:soso_e112:}
据说男厕所卫生老是搞不好,在上面贴上“前近一小步,文明一大步”,英文大致意思是要小心瞄准,之类的标语,也不管用。后来把标语改了,一下卫生就搞好了。标语是这样的:如果尿不进尿槽,说明你的东西太短了。

点评

哈哈,黄老师不愧是黄老师啊!  详情 回复 发表于 2014-11-22 13:46
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 264个

财富等级: 日进斗金

发表于 2014-11-22 13:46:03 来自手机 | 显示全部楼层
/db_自贡黄明儒_ 发表于 2014-11-22 13:24
iLisp喜欢听,我就讲讲,如果被版主封贴了,你要负责任
据说男厕所卫生老是搞不好,在上面贴 ...

哈哈,黄老师不愧是黄老师啊!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2014-11-25 03:13:28 | 显示全部楼层
射线法改进一下,射线给一个非整数角度,只要判断点不在曲线上,出现凹弧3点共线的几率是微乎其微的(可以忽略)
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1487个

财富等级: 财源广进

发表于 2019-7-30 15:35:20 | 显示全部楼层
本帖最后由 flowerson 于 2019-7-30 15:38 编辑

楼主,发现了错误。点取云线附近会出错。类似下面的提示:“选择曲线:; 错误: 参数类型错误: numberp: (-264910.0 105537.0 0.0)”附件为dwq图纸。请楼主帮检测是什么原因?云线以外程序是正常的。

问题.jpg

有问题.zip

24.54 KB, 阅读权限: 10, 下载次数: 1, 下载积分: D豆 -1 , 活跃度 1

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-3-29 21:45 , Processed in 0.472125 second(s), 63 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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