找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2790|回复: 8

[教学] XDGE几何库应用(15)--认识 AcGeBoundBlock2d & 3d

[复制链接]

已领礼包: 1268个

财富等级: 财源广进

发表于 2014-9-23 08:40:05 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 st788796 于 2014-11-1 08:04 编辑

AcGeBoundBlock2d 和 AcGeBlock3d 几何边界体,这样说比较抽象,对 Lisper 说起 vla-getboundingbox 就熟悉了,前者是二维平面,后者是三维空间,下面以 AcGeBoundBlock3d 为例介绍

AutoCAD 中用到的实体或 AcGe 类,除了 Ray (有起点没有上界) XLine(无限直线,没有上界也没有下界),其他实体都可以用一个“盒子”包住,这个特性就是边界体。

在 vla-getboundingbox 中获取的这个边界体始终是与 坐标轴 (WCS)对齐的,在 AcGe 中每个 Enity2d (Entity3d) 的边界体也是如此,但是从这个类的构造来说,除了正六面体外,还可以构造平行六面体的。

先来看看 AcGeBoundBlock3d 构造方法

1 (setq a (xdge::constructor "kBoundBlock3d"))
默认构造一个 '((0.0 0.0 0.0) (0.0 0.0) (0.0 0.0 0.0) (0.0 0.0 0.0) 原点的边界体

2 (setq a (xdge::constructor "kBoundBlock3d" basePnt dir1 dir2 dir3))
以 basePnt 为基点,dir1 dir2 dir3 三个方向长度矢量,这里矢量不在坐标轴上就是一个平行六面体了

另外是复制构造方法,从略。

有了这个边界除了 Lisp 中最常用的画出这个“盒子”,还有其它可以利用特性吗?下面看看 这个类的属性和方法

1 extend 扩展边界体的边,将点加入边界体,如果点在边界体内,忽略,如果超出边界,重新构造边界体,使得边界体包含这个点,看一个具体应用,Lisp 中经常用到的点集包围盒,一般这样写
  1. (setq minp (apply 'mapcar (cons 'min pts))
  2.         maxp (apply 'mapcar (cons 'max pts))
  3. )

用边界体就是这样,首先构造一个默认的 AcGeBoundBlock3d,然后遍历点集逐一加入重新构造这个边界体
  1. (setq a (xdge::constructor "kBoundBlock3d"))
  2. (foreach p pts
  3.   (xdge::setpropertyvalue a "extend" p)
  4. )
  5. (xdge::getpropertyvalue a "getMinMaxPoints")


2 getMinMaxPoints 这个好理解了,返回最小的下界坐标及最大的上界坐标,和 vla-getbounding 对 Object 的返回值一样
(xdge::getpropertyvalue a "getMinMaxPoints")

3 get 获取 AcGeBoundBlock3d 信息,输出 基点及三个方向的矢量
(xdge::getpropertyvalue a "get")

4 isBox 判断 AcGeBoundBlock3d 是不是一个坐标系统的Box,是返回 T,否则 nil
(xdge::getpropertyvalue a "isBox")

5 contains 判断点是否属于 AcGeBoundBlock3d,这个功能可以用来判断点是否在 BOX 内!注意点在边界上也属于边界体
(xdge::getpropertyvalue a "contains" pnt)

6 isDisjoint 判断两个边界体是否相交,不相交 T,相交 nil,这方法可以用在 求两个实体相交时的快速排斥上
(xdge::getpropertyvalue a "isDisjoint" b)  b 为另一AcGeBoundBlock3d

7 swell 将边界扩展一个距离
(xdge::setpropertyvalue a "swell" 100.)

本帖被以下淘专辑推荐:

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

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2014-9-23 08:58:08 | 显示全部楼层
本帖最后由 st788796 于 2014-9-23 09:16 编辑

用下面这个曲线集 Box 理解上面一些函数用法
  1. (defun c:tt (/ ss box gel gbox)
  2.   (if (setq ss (ssget '((0 . "*polyline,line,circle,arc,ellipse")))) ;_没有 ray xline mline
  3.     (progn
  4.       (setq gel         (mapcar 'xdge::constructor (xdrx_pickset->ents ss)) ;_转换为 Ge 实体表
  5.             box         (xdge::getpropertyvalue (car gel) "BoundBlock");_构造一个初始 BoundBlock
  6.             gbox (mapcar
  7.                    '(lambda (x / gb)
  8.                       (setq
  9.                         gb (xdge::getpropertyvalue x "BoundBlock")
  10.                       ) ;_获取 AcGeBoundBlock
  11.                       (xdge::getpropertyvalue gb "getMinMaxPoints") ;_获取对交点
  12.                     )
  13.                    (cdr gel)
  14.                  )
  15.       )
  16.       (mapcar '(lambda (x)
  17.                  (mapcar '(lambda (p)
  18.                             (xdge::setpropertyvalue box "extend" p) ;_将点加入 AcGeBoundBlock3d
  19.                            ;; (xdge::setpropertyvalue box "setToBox")
  20.                           )
  21.                          x
  22.                  )
  23.                )
  24.               gbox
  25.       )
  26.       (apply 'xdrx_line_make
  27.              (xdge::getpropertyvalue box "getMinMaxPoints")
  28.       ) ;_获取新的边界点
  29.     )
  30.   )
  31.   (princ)
  32. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2014-9-23 17:52:41 | 显示全部楼层
在程序中如果用到 点选,首先要把点放到屏幕内,下面这个演示用 AcGeBoundBlock3d  的 contains 和 swell 特性完成这个
  1. (defun c:tt (/ ss box pc scl gbox)
  2.   (if (setq ss (ssget))
  3.     (progn
  4.       (setq box (xdrx_entity_box ss)) ;_选择集盒子
  5.       (setq pc         (getvar "viewctr") ;_中心点
  6.             pbox (getvar "screensize")
  7.             scl         (/ (getvar "viewsize") (cadr pbox)) ;_像素转图形单位
  8.             v         (xdrx_vector_product pbox scl) ;_屏幕长宽(图形单位)
  9.             gbox (xdge::constructor
  10.                    "kBoundBlock3d"
  11.                    (mapcar
  12.                      '-
  13.                      pc
  14.                      (list (* (car v) 0.5) (* (cadr v) 0.5) 0.)
  15.                    )
  16.                    (list (car v) 0.0 0.0)
  17.                    (list 0.0 (getvar "viewsize") 0.0)
  18.                    (list 0.0 0.0 0.)
  19.                  ) ;_构造一个屏幕 BoundBlock3d
  20.       )
  21.       (if
  22.         (or (not (xdge::getpropertyvalue gbox "contains" (car box))) ;_左下角点是否在 BoundBlock3d
  23.             (not (xdge::getpropertyvalue gbox "contains" (caddr box))) ;_右上角点是否在 BoundBlock3d
  24.         )
  25.          (progn
  26.            (xdge::setpropertyvalue gbox (car box) (caddr box)) ;_重新设置 BoundBlock
  27.            (xdge::setpropertyvalue
  28.              gbox
  29.              "swell"
  30.              (* 1.2 (abs (- (cadr (last box)) (cadar box))))
  31.            );_将 BoundBlock3d 的边界向外偏移
  32.            (apply 'xdrx_document_zoomwindow
  33.                   (xdge::getpropertyvalue gbox "getMinMaxPoints")
  34.            );_获取对交点缩放
  35.          )
  36.       )
  37.     )
  38.   )
  39.   (xdge::free)
  40.   (princ)
  41. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 19个

财富等级: 恭喜发财

发表于 2014-9-23 18:09:03 | 显示全部楼层
大师,这个BOX能不能是斜的?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2014-9-23 19:46:28 | 显示全部楼层
Lisphk 发表于 2014-9-23 18:09
大师,这个BOX能不能是斜的?

可以,看下面的测试,按斜放的 Pline 矩形构造 AcGeBoundBlock3d
  1. (defun c:tt (/ ss gel PlineToGeBox)
  2.   (defun PlineToGeBox (e / pts bp vx vy)
  3.     (setq pts (xdrx_getpropertyvalue e "vertices")
  4.           bp  (car pts)
  5.           vx  (mapcar '- (cadr pts) bp)
  6.           vy  (mapcar '- (last pts) bp)
  7.     )
  8.     (xdge::constructor "kBoundBlock3d" bp vx vy '(0. 0. 0.))
  9.   )
  10.   (if (setq ss (ssget '((0 . "LWPOLYLINE"))))
  11.     (progn
  12.       (setq gel        (mapcar        '(lambda (x)
  13.                            (list (PlineToGeBox x)
  14.                                  (xdrx_getpropertyvalue x "color")
  15.                            )
  16.                          )
  17.                         (xdrx_pickset->ents ss)
  18.                 )
  19.       )
  20.       (while (setq p (getpoint "\n测试点: "))
  21.         (mapcar
  22.           '(lambda (x)
  23.              (if (xdge::getpropertyvalue (car x) "contains" p)
  24.                (princ (strcat "\n点位于颜色 " (itoa (cadr x)) " 区域!"))
  25.              )
  26.            )
  27.           gel
  28.         )
  29.       )
  30.       (xdge::free)
  31.     )
  32.   )
  33.   (princ)
  34. )
boundblock1.gif

点评

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

使用道具 举报

已领礼包: 19个

财富等级: 恭喜发财

发表于 2014-9-23 20:25:52 | 显示全部楼层
st788796 发表于 2014-9-23 19:46
可以,看下面的测试,按斜放的 Pline 矩形构造 AcGeBoundBlock3d

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

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2014-9-23 20:47:01 | 显示全部楼层
Lisphk 发表于 2014-9-23 20:25
给讲讲怎么构造那个斜的BOX呗。

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

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

发表于 2014-9-23 22:14:21 来自手机 | 显示全部楼层
extents例子中不能构造默认的AcGeBoundBlock3d,应取第一个实体构造,否则有可能( 0 0 0)会成为上界或下界和真实的不一样
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2014-9-28 13:59:08 | 显示全部楼层
本帖最后由 st788796 于 2014-9-28 14:18 编辑

在手册说明中这个 bounBlock 是平行于坐标系统,AutoCAD 中的实体记录是 OCS,而且这个 OCS 是和 WCS 一致,这样确定形状的 Ge 实体,无论移动到什么位置、你看到是何种 UCS ,其 boundBlock 是相同,只不过把这个 boundBlock  表现到 当前 Ucs 只需要将这个点转换一次,实体无需变换,看下面测试代码
  1. (defun c:tt (/ e ge pts bound)
  2.   (if (and (setq e (entsel))
  3.            (setq ge (xdge::constructor (car e)))
  4.            (setq bound (xdge::getpropertyvalue ge "boundBlock"))
  5.            (setq pts (xdge::getpropertyvalue bound "getMinMaxPoints"))
  6.       )
  7.     (progn (apply 'command
  8.                   (cons        "_.line"
  9.                         (xdrx_points_transform pts (xdrx_matrix_wcs2ucs))
  10.                   );_boundBlock 是 WCS
  11.            );_这里 command 是以当前坐标绘制
  12.            (command "")
  13.     )
  14.   )
  15.   (princ)
  16. )

都是在 WCS 下操作
  1. (defun c:tt (/ e ge pts bound)
  2.   (if (and (setq e (entsel))
  3.            (setq ge (xdge::constructor (car e)))
  4.            (setq bound (xdge::getpropertyvalue ge "boundBlock"))
  5.            (setq pts (xdge::getpropertyvalue bound "getMinMaxPoints"))
  6.       )
  7.     (apply 'xdrx_line_make pts)
  8.   )
  9.   (princ)
  10. )
boundblock2.gif
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-23 22:11 , Processed in 0.200877 second(s), 53 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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