CGAL的D维包围盒相交计算

news2025/1/17 4:13:42

        包围盒相交测试是一种用于快速判断两个三维对象是否相交的方法,而AABB树则是一种数据结构,常用于加速场景中的射线检测和碰撞检测。

        首先,让我们了解一下包围盒相交测试。这种测试的目的是为了快速判断两个三维对象是否相交,而不需要进行细致的几何形状相交测试。常见的包围盒类型包括轴对齐包围盒(Axis-Aligned Bounding Box,简称AABB)和方向包围盒(Oriented Bounding Box,简称OBB)等。

        对于两个包围盒是否相交的判断,通常采用分离轴定理(Separating Axis Theorem)进行快速判断。该定理指出,如果两个凸多面体不相交,那么至少存在一个平面,使得这两个多面体在该平面的一侧。因此,对于两个AABB,我们可以分别找到它们各自的六个面,然后判断这些面是否在同一直线上。如果存在同一直线上的两个面,那么这两个AABB必定相交。

        接下来,让我们了解一下AABB树。AABB树是由AABB包围盒结点构成的二叉树,常用来加速场景中的射线检测和碰撞检测。树的每个结点都是一个包围盒,且结点的包围盒包裹了所有子结点的包围盒。由于是二叉树,则碰撞查询的时间复杂度是O ( log(n) )。AABB树是一颗满二叉树,对象只存在于叶结点中,父结点的包围盒包含了子结点的包围盒。

        在AABB树中进行碰撞检测的基本思路是:首先检测最大的包装盒是否相交(AABB级别),如果相交了,它们可能(注意,只是可能)发生了碰撞,接下来将进一步地递归处理它们(OBB级别),不断地递归用下一级进行处理。如果沿着下一级发现子树并没有发生相交,这时就可以停止,并得出结论没有发生碰撞。如果发现子树相交,那么要进一步处理它的子树直到到达叶子节点,并最终得出结论。

        综上所述,包围盒相交测试和AABB树都是计算机图形学中用于提高渲染和碰撞检测效率的重要工具。它们虽然原理和应用有所不同,但都是为了提高三维对象的处理效率而发展出来的技术。 

1、介绍

        如果基本体不再那么简单,例如三维三角形和多面体表面的小平面,那么关于几何基本体的简单问题,如相交和距离计算,本身可能会变得相当昂贵。因此,在这些基元上操作的算法在实践中往往是缓慢的。一种常见的(启发式)优化方法通过其轴对齐的边界框来近似几何图元,在框上运行适当的算法修改,并且每当一对框具有有趣的交互时,只有在框中包含的复杂几何图元上才能计算出确切的答案。

        我们提供了一种有效的算法,用于找到大量等向框的所有相交对,即,通常这些框将是更复杂几何形状的边界框。该算法的一个直接应用是检测多面体表面的所有交点(和自交点),即将该算法应用于空间中的一大组三角形,我们将在本章稍后给出一个示例程序。不太明显的应用是这些曲面之间的邻近性查询和距离计算,请参见第节“使用自定义特征类进行点邻近性搜索的示例”,以及了解更多详细信息。 

2、定义

        d维等向性盒被定义为d个间隔的笛卡尔积。如果d个间隔{[loi,hii]|0≤i<d}是半开区间,则我们称该盒为半开盒,如果d个间隔{[loi,hii]|0≤i<d}是闭区间,则我们称该盒为闭盒。请注意,闭盒支持零宽度盒,它们可以在其边界处相交,而非空半开盒总是具有正体积,并且只有当它们的内部重叠时才会相交。闭盒和半开盒之间的区别不需要对盒进行不同的表示,只需要在比较盒时进行不同的解释,这是由拓扑参数的两个可能值选择的:

        Box_intersection_d:: HALF_OPEN 和 Box_intersection_d:: CLOSED。区间边界的数字类型必须是内置类型 int、unsigned int、double 或 float 之一。

        此外,一个盒子有一个唯一的id号。即使盒子具有相同的坐标,它也用于在每个维度上一致地排序盒子。因此,该算法保证一对相交的盒子只被报告一次。请注意,具有相同id号的盒子不会被报告,因为它们显然是相互交叉的。

        盒子相交算法有两种形式:一种算法处理单个盒子序列并计算所有成对交集,称为完全情况,例如在自交测试中使用。另一种算法处理两个盒子序列,并计算第一个序列中的盒子与第二个序列中的盒子之间的成对交集,称为二分情况。对于每个发现的成对交集,都会调用一个具有两个参数的回调函数;第一个参数是第一个序列中的盒子,第二个参数是第二个序列中的盒子。在完全情况下,第二个参数是第一个序列的内部副本中的盒子。

3、软件设计

        盒交集算法被实现为一个通用函数族;完全情况下的函数接受一个迭代器范围,二分情况下的功能接受两个迭代者范围。用于报告相交对的回调函数是作为BinaryFunction概念的模板参数提供的。使用所有默认参数的两个主要函数调用如下所示:

#include <CGAL/box_intersection_d.h>
template< class RandomAccessIterator, class Callback >
void box_intersection_d(RandomAccessIterator begin,
                        RandomAccessIterator end,
                        Callback callback);
template< class RandomAccessIterator1,
          class RandomAccessIterator2,
          class Callback >
void box_intersection_d(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
                        RandomAccessIterator2 begin2, RandomAccessIterator2 end2,

         函数调用的其他参数是调整性能权衡的截止值,以及在拓扑上封闭的盒子(默认)和拓扑上半开放的盒子之间进行选择的拓扑参数。

        该算法在算法过程中对盒子进行重新排序。现在,根据盒子的尺寸,复制盒子或使用指向盒子的指针并仅复制指针可能更快。我们为这两种选项提供自动支持。为了简化描述,让我们将迭代器范围的值类型称为盒子句柄。盒子句柄可以是我们的盒子类型本身,也可以是盒子类型的指针(或 const 指针);这些选择代表了上述两种选项。

        一般来说,这些算法将box类型视为不透明类型,并假设它们是Assignable概念的模型,因此算法可以修改输入序列并重新排列box。对box维度和box坐标的访问是通过BoxIntersection Traits_d概念的traits类来介导的。提供了一个默认的traits类,该类假设box类型是BoxIntersection Box_d概念的模型,并且box句柄,即迭代器值类型,与box类型相同或指向box类型(参见前一段关于box句柄的值与指针特性的描述)。

        提供了面向 ISO 的两个实现:Box_intersection_d::Box_d 作为普通盒子,Box_intersection_d::Box_with_handle_d 作为盒子加上一个手柄,可用于指向由盒子近似表示的完整几何体。 这两个实现都有模板参数,用于区间边界的数字类型、盒子的固定维度和策略类[1],用于在提供 ID 编号的多个解决方案中进行选择。

        二分情况下的函数签名如下。除了单个迭代器范围之外,带有 box_self_intersection_d() 函数的完整情况的签名看起来是一样的。

#include CGAL/box_intersection_d.h
template< class RandomAccessIterator1,
          class RandomAccessIterator2,
          class Callback >
void box_intersection_d(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
                        RandomAccessIterator2 begin2, RandomAccessIterator2 end2,
                        Callback callback, std::ptrdiff_t cutoff = 10,
                        Box_intersection_d::Topology topology = Box_intersection_d::CLOSED,
                        Box_intersection_d::Setting setting = Box_intersection_d::BIPARTITE);
template< class RandomAccessIterator1,
          class RandomAccessIterator2,
          class Callback, class BoxTraits >
void box_intersection_d(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
                        RandomAccessIterator2 begin2, RandomAccessIterator2 end2,
                        Callback callback, BoxTraits box_traits,
                        std::ptrdiff cutoff = 10,
                        Box_intersection_d::Topology topology = Box_intersection_d::CLOSED,
                        Box_intersection_d::Setting setting = Box_intersection_d::BIPARTITE);

4、性能

        实现的算法在[2]中被描述为版本二。它的性能取决于一个截止参数。当两个迭代器范围的大小都低于截止参数时,函数将从流分段树算法切换到双向扫描算法,有关详细信息,请参阅[2]。

        流式分段树算法需要O(nlogd(n)+k)最坏情况下的运行时间和O(n)空间,其中n是两个输入序列中的盒子数量,d是盒子的(常数)维数,k是输出复杂度,即盒子的成对交集的数量。双向扫描算法需要O(nlog(n)+l)最坏情况下的运行时间和O(n)空间,其中l是一维(使用算法而不是分段树的维度)中成对重叠间隔的数量。注意,l不一定与k有关,并且使用双向扫描算法是一种启发式算法。

        不幸的是,我们没有通用的方法来自动确定最佳截止参数,因为它取决于所使用的硬件、回调运行时和段树运行时之间的运行时比率,当然还有要检查的框的数量及其分布。在回调运行时占主导地位的情况下,最好将阈值参数设置得较小。否则,截止值=n--√可以导致可接受的结果。对于分布良好的盒子,论文[2]给出了数千个最佳截断值。无论如何,为了获得最佳运行时间,建议进行一些实验来比较不同的截止参数。

        为了证明方框相交可以很快完成,不同的方框序列在总共4到800000个方框的范围内相交。我们使用闭合拓扑的三维默认框,带有浮动坐标,没有额外的数据字段。该算法直接作用于框,而不是作用于指向框的指针。每个方框交叉点都报告给一个空的伪回调。

        对于每个盒子集,使用自适应近似来确定接近最优的截止参数。将流传输所需的运行时间与通常的扫描进行比较。在具有4GB主内存的Xeon 2.4GHz上的结果如图91.1所示。对于少数盒子,纯扫描仍然比具有最佳截止的流式传输更快,这只会将盒子集委托给扫描算法。随着盒子越来越多,开销变得不那么重要了。

扫描和流算法之间的运行时比较。 

5、其他

        Box_intersection_d模块提供了一种高效的方式来检测多个三维对象是否相交。它使用了一种基于分离轴定理的算法,通过快速判断两个包围盒是否相交来避免进行繁琐的几何形状相交测试。

        在Box_intersection_d模块中,包围盒的类型可以是Axis-Aligned Bounding Box(AABB)或Oriented Bounding Box(OBB)。该模块提供了各种函数和数据结构,用于创建、查询和管理包围盒对象。

        此外,Box_intersection_d模块还提供了一些高级功能,如动态更新包围盒、支持不同维度的几何对象等。它还与其他CGAL模块集成,如Mesh_complex、Arrangement等,以提供更完整的几何处理解决方案。

        Box_intersection_d::Box_d<double,2> 提供的 box 实现有一个专用的构造函数用于创建 Autorad 包围盒类型 Bbox_2(对于维度 3 也是如此)。我们在我们的最小示例中使用它,在 3×3 的网格布局中轻松创建了九个二维盒子
此外,我们选择中心框和右上角框作为我们的第二个框序列查询。

        box类型的默认策略在框中用显式计数器实现id-number,这是默认选择,因为它总是有效,但它会占用空间。

        我们使用自己的box类box遵循BoxIntersectionBox_d概念,它允许我们重用默认的traits实现,即,我们可以使用相同的默认函数调用来计算所有交集。

        Box_intersection_d::HALF_OPEN:这个常量可能表示盒子的边界是半开放的。在几何学中,一个半开放的边界意味着盒子不包括其边界上的点。例如,考虑一个 2D 盒子,其边界是一个矩形。如果盒子的边界是半开放的,那么矩形的上边和下边是开放的,这意味着它们不包含在盒子的内部。在某些算法和应用中,半开放的边界可能是有用的,因为它允许盒子包含其边界上的点,同时仍然保持盒子的封闭性。

        Box_intersection_d::CLOSED:这个常量可能表示盒子的边界是封闭的。这意味着盒子包括其边界上的所有点。在上面的 2D 矩形例子中,如果盒子的边界是封闭的,那么矩形的上边和下边都包含在盒子的内部。在其他算法和应用中,封闭的边界可能是必要的,以确保盒子完全包含其内容。

      Bbox_2 bb = pA[j].bbox() + pA[j+1].bbox();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1340460.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据仓库 基本信息

数据仓库基本理论 数据仓库&#xff08;英语&#xff1a;Data Warehouse&#xff0c;简称数仓、DW&#xff09;,是一个用于存储、分析、报告的数据系统。数据仓库的目的是构建面向分析的集成化数据环境&#xff0c;为企业提供决策支持&#xff08;Decision Support&#xff09…

【轻松入门】OpenCV4.8 + QT5.x开发环境搭建

引言 大家好&#xff0c;今天给大家分享一下最新版本OpenCV4.8 QT5 如何一起配置&#xff0c;完成环境搭建的。 下载OpenCV4.8并解压缩 软件版本支持 CMake3.13 或者以上版本 https://cmake.org/ VS2017专业版或者以上版本 QT5.15.2 OpenCV4.8源码包 https://github.com/op…

主浏览器优化之路1——你现在在用的是什么浏览器?Edge?谷歌?火狐?360!?

上一世&#xff0c;我的浏览器之路 引言为什么要用两个浏览器为什么一定要放弃火狐结尾给大家一个猜数字小游戏&#xff08;测运气&#xff09; 引言 小时候&#xff0c;我一开始上网的浏览器是2345王牌浏览器吧&#xff0c; 因为上面集成了很多网站&#xff0c;我记得上面有7…

【MySQL】多表连接查询

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; 数 据 库 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 1. 交叉连接&#xff08;CROSS JOIN&#xff09; 2. 内连接&#xff08;INNER JOIN&#xff09; 3. 外连接 结语 我的…

几款软件助您事半功倍

在如今繁忙而竞争激烈的工作环境中&#xff0c;寻找适合自己的工作软件是提高工作效率、优化工作流程的重要一环。为了帮助你更好地管理任务、组织工作和提高生产力&#xff0c;我将向你推荐四款备受推崇的工作软件&#xff0c;并详细介绍它们各自的功能和特点。 1. Zoom&#…

记录使用minikube部署web程序,并灰度发布不同版本

1. 安装软件 1.1安装docker desktop 下载地址 重点&#xff1a;配置镜像加速 1.2 安装k8s&minikube 这里参考阿里社区的配置 minikube1.24.0版本下载地址 重点&#xff1a;安装版本问题【因为后面要用阿里云的服务来获取所需Docker镜像&#xff0c;一直不成功使用的高版…

软件测试/测试开发丨Pytest学习笔记

Pytest 格式要求 文件: 以 test_ 开头或以 _test 结尾类: 以 Test 开头方法/函数: 以 _test 开头测试类中不可以添加构造函数, 若添加构造函数将导致Pytest无法识别类下的测试方法 断言 与Unittest不同, 在Pytest中我们需要使用python自带的 assert 关键字进行断言 assert…

JOSEF约瑟 双位置继电器 DCS-12/110V 线圈电压直流110V 板前安装

系列型号&#xff1a; DCS-11双位置继电器&#xff1b; DCS-12双位置继电器&#xff1b; DCS-13双位置继电器&#xff1b; RXMVB2 RK 251 204双位置继电器&#xff1b; RXMVB2 RK 251 205双位置继电器&#xff1b; RXMVB2 RK 251 106双位置继电器&#xff1b; 一、用途 …

Flink项目实战篇 基于Flink的城市交通监控平台(下)

系列文章目录 Flink项目实战篇 基于Flink的城市交通监控平台&#xff08;上&#xff09; Flink项目实战篇 基于Flink的城市交通监控平台&#xff08;下&#xff09; 文章目录 系列文章目录4. 智能实时报警4.1 实时套牌分析4.2 实时危险驾驶分析4.3 出警分析4.4 违法车辆轨迹跟…

6.Nacos

1.单机部署 1.1 官网 https://nacos.io/zh-cn/index.html https://github.com/alibaba/Nacos 1.2.版本说明 https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E 1.3.下载地址 https://github.com/alibaba/nacos/releases/tag/2.2.…

百度CTO王海峰:飞桨开发者已达1070万

目录 写在前面 飞桨开发者已达1070万 文心一言用户规模破亿&#xff0c;日提问量快速增长 写在前面 “文心一言用户规模突破1亿。”12月28日&#xff0c;百度首席技术官、深度学习技术及应用国家工程研究中心主任王海峰在第十届WAVE SUMMIT深度学习开发者大会上宣布。会上&…

全平台去水印系统源码:画质高清无损害,一键下载 支持目前主流80多个平台无水印下载 带完整的安装部署教程

在数字内容爆炸的时代&#xff0c;图片和视频的传播和使用越来越频繁。然而&#xff0c;许多优质资源都带有水印&#xff0c;不仅影响了美观&#xff0c;也在一定程度上限制了资源的再利用。传统的去水印方法往往操作复杂&#xff0c;效果不尽如人意&#xff0c;甚至可能损害原…

《网络是怎样连接的》1.2、1.3节图表(自用)

图2.1&#xff1a;浏览器调用socket库中的解析器&#xff0c;向DNS服务器询问域名的ip地址 &#xff08;图中的gethostbyname是解析器的名称&#xff1b;协议栈是操作系统的网络控制软件&#xff0c;也称协议驱动、TCP/IP驱动&#xff09; 图2.2 DNS服务器根据客户端查询信息查…

Vue2.0 -- 组件局部注册

目录 组件定义 注册 使用组件 组件的命名 再做vue之前, 需要先引入vue.js文件 <script src"../js/vue.js"></script>有很多官方或者非官方的cdn可以使用, 可自行前往 搜索下载 组件定义 首先, 使用Vue.extend() 来定义一个组件 (注意这个步骤是在sc…

mac 生成 本地.ssh

输入下面命令行 ssh-keygen 默认回车得到下面的 Generating public/private rsa key pair. Enter file in which to save the key (/Users/{用户名}/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has be…

【 FPGA 封装设计资源 】 Xilinx vs Altera

XILINX PACKAGE 一般在doc nav搜索&#xff0c;同样也可以在官网&#xff1b;检索关键字“*pkg-pinout.” 比如vu9p: ug575-ultrascale-pkg-pinout.pdf 原理库文件 Package Files Portal 举例&#xff1a; 先选封装&#xff1b; 再选器件 二维交叉检索后&#xff0c;在右击…

【力扣题解】P404-左叶子之和-Java题解

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【力扣题解】 文章目录 【力扣题解】P404-左叶子之和-Java题解&#x1f30f;题目描述&#x1f4a1;题解&#x1f30f;总结…

配置inotify+rsync实时同步

Linux内核从2.6.13版本开始提供了inotify通知接口&#xff0c;用来监控文件系统的各种变化情况&#xff0c;如 文件存取&#xff0c;删除、移动&#xff0c;修改等&#xff0c;利用这一机制&#xff0c;可以非常方便地实现文件异动告警、增量备份&#xff0c; 并针对目录或文件…

main函数的参数ac和av

概要&#xff1a; main函数有两个参数&#xff0c;ac和av ac表示参数的个数&#xff0c;程序名包括在内。也就是说程序无参数运行时&#xff0c;ac的值为1 av是一个字符串数组&#xff0c;这个数组中的每个元素表示一个参数&#xff0c;程序名包括在内。也就是说&#xff0c…

Zulip:开源团队协作工具,高效沟通与远程办公 | 开源日报 No.126

zulip/zulip Stars: 18.9k License: Apache-2.0 Zulip 是一个开源的团队协作工具&#xff0c;拥有独特的基于主题的线程功能&#xff0c;结合了电子邮件和聊天的优点&#xff0c;使远程工作更加高效和愉快。它是唯一设计用于实时和异步对话的现代团队聊天应用程序。 其核心优势…