CGAL的D维包围盒相交计算

        包围盒相交测试是一种用于快速判断两个三维对象是否相交的方法,而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.mzph.cn/news/582523.shtml

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

相关文章

同化的题解

时间限制: 1000ms 空间限制: 524288kB 题目描述 古人云&#xff1a;“近朱者赤近墨者黑”。这句话是很有道理的。这不鱼大大和一群苦命打工仔被安排进厂拧螺丝了。 进厂第一天&#xff0c;每个人拧螺丝的动力k都是不同且十分高涨的。但是当大家坐在一起后会聊天偷懒&#xf…

在微服务中如何实现全链路的金丝雀发布?

目录 1. 什么金丝雀发布&#xff1f;它有什么用&#xff1f; 2.如何实现全链路的金丝雀发布 2.1 负载均衡模块 2.2 网关模块 2.3 服务模块 2.3.1 注册为灰色服务实例 2.3.2 设置负载均衡器 2.3.3 传递灰度发布标签 2.4 其他代码 2.4.1 其他业务代码 2.4.2 pom.xml 关…

CSS 向上扩展动画

上干货 <template><!-- mouseenter"startAnimation" 表示在鼠标进入元素时触发 startAnimation 方法。mouseleave"stopAnimation" 表示在鼠标离开元素时触发 stopAnimation 方法。 --><!-- 容器元素 --><div class"container&q…

SAP VA01 创建带wbs号的销售订单包 CJ067的错误

接口错误提示如下 SAP官方 CJ067 124177 - VA01: CJ067 during WBS acct assgmt with a different business area S4的core 刚好能用上 实施 这个note后成功

引力魔方的操作知识

引力魔方的一些操作以及问题如图所示&#xff1a; 主要包含以下内容&#xff1a; 1.如何搭建计划&#xff1f; 2.创意素材说明&#xff1b; 3.如何出价&#xff1f; 4.如何提高引力魔方点击率&#xff1f; 5.如何优化定向和溢价&#xff1b; 6.冷启动&#xff1a;计划开…

基于WEB的网上购物系统的设计与实现(附:源码 论文 sql文件)

摘 要 随着计算机网络技术的飞速发展和人们生活节奏的不断加快&#xff0c;电子商务技术已经逐渐融入了人们的日常生活当中&#xff0c;网上商城作为电子商务最普遍的一种形式&#xff0c;已被大众逐渐接受。因此开发一个网上商城系统&#xff0c;适合当今形势&#xff0c;更加…

DRF从入门到精通六(排序组件、过滤组件、分页组件、异常处理)

文章目录 一、排序组件继承GenericAPIView使用DRF内置排序组件继承APIView编写排序 二、过滤组件继承GenericAPIView使用DRF内置过滤器实现过滤使用第三方模块django-filter实现and关系的过滤自定制过滤类排序搭配过滤使用 三、分页组件分页器一&#xff1a;Pagination&#xf…

【JavaScript】闭包机制

✨ 专栏介绍 在现代Web开发中&#xff0c;JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性&#xff0c;还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言&#xff0c;JavaScript具有广泛的应用场景&#x…

java设计模式学习之【解释器模式】

文章目录 引言解释器模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用表达式解析示例代码地址 引言 在我们的日常生活中&#xff0c;语言的翻译和理解是沟通的关键。每种语言都有自己的语法规则&#xff0c;而翻译人员和计算机程序需要理解并遵循这些规则来…

手写Promise

目录 前言 状态 使用方法 构造函数 对象 结论 第一阶段 搭建基本结构 思路 代码实现 测试一下 实现then方法获取异步值 思路 改造代码如下 测试一下 成功场景 失败场景 实现类的resolve,reject以及catch方法 思路 代码实现 测试一下 第一阶段总结 第二阶…

《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识(11)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识&#xff08;10&#xff09; 1.3 PCI总线的存储器读写总线事务 1.3.2 Posted和Non-Posted传送方式 PCI总线规定了两类数据传送方式&#xff0c;分别是Posted和Non-Posted数据传送…

关于Redis面试题

前言 之前为了准备面试&#xff0c;收集整理了一些面试题。 本篇文章更新时间2023年12月27日。 最新的内容可以看我的原文&#xff1a;https://www.yuque.com/wfzx/ninzck/cbf0cxkrr6s1kniv Redis 是什么 全名&#xff1a;远程字典服务。这是一个开源的在内存中的数据结构存…

硅像素传感器文献调研(二)

写在前面&#xff1a;从上篇文章的参考文献中看到一篇文献&#xff0c;现在也精读一下&#xff0c;今天还有一个任务是把上篇文献整体脉络用流程图的形式完整梳理一下。 哈哈哈哈哈哈&#xff1a;代表没太搞明白的部分 如何写论文&#xff1a; 引言部分&#xff1a;基础理论…

Python入门知识点分享——(十一)if条件语句

if条件语句是一种编程语言中用于控制程序流程的结构。它根据一个条件的真假来决定执行不同的代码块。 if条件语句通常由if关键字、一个条件表达式和一个代码块组成。条件表达式可以是一个返回布尔值的表达式&#xff0c;如果条件为真&#xff0c;则执行代码块中的代码&#xf…

01_软件测试

01_软件测试 学习目标 1、能复述软件测试的定义 2、能说出7种测试分类的区别 3、能说出质量模型的重点5项 4、能说出测试流程的6个步骤 5、能说出测试模板8个要素 认识软件及测试 什么是软件 软件&#xff1a;控制计算机硬件工作的工具 软件的基本组成 软件生产过程 什么是软…

vue多条数据渲染(带图片)

我在这用的为接口数据&#xff1a; 先调用接口获取需要的数据: 然后用&#xff1a;data绑定需要渲染的数据&#xff1b;&#xff08;记得包裹在<el-table>标签中&#xff09; 然后以此循环渲染数据&#xff1b;那怎么渲染出来图片呢&#xff1f; 在<el-table-column…

Vue3-25-路由-路由的基本使用

对路由的理解 路由 &#xff1a; 就是前端对页面路径的拦截&#xff0c;根据不同的路径渲染不同的组件&#xff0c; 从而实现单页应用中的页面局部刷新的功能。安装路由依赖 根据使用的不同的包管理工具采用不同的命令&#xff0c; 常见的三种包管理工具和对应的命令如下&…

day44 1228

作业1&#xff1a; #include <iostream>using namespace std;class Person {int *age;string &name; public:Person(int age,string &name):age(new int(age)),name(name){cout << "Person的构造函数" <<endl;}~Person(){delete age;cout…

【Java系列】多线程案例学习——基于阻塞队列实现生产者消费者模型

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【Java系列专栏】【JaveEE学习专栏】 本专栏旨在分享学习JavaEE的一点学习心得&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录…

如何在Mac中设置三指拖移,这里有详细步骤

三指拖移手势允许你选择文本&#xff0c;或通过在触控板上用三指拖动窗口或任何其他元素来移动它。它可以用于快速移动或调整窗口、文件或图像在屏幕上的位置。 然而&#xff0c;这个手势在默认情况下是禁用的&#xff0c;因此在本教程中&#xff0c;我们将向你展示如何在你的…