3D包容盒子

原理简述

        包围体(包容盒)是一个简单的几何空间,里面包含着复杂形状的物体。为物体添加包围体的目的是快速的进行碰撞检测或者进行精确的碰撞检测之前进行过滤(即当包围体碰撞,才进行精确碰撞检测和处理)。包围体类型包括球体、轴对齐包围盒(AABB)、有向包围盒(OBB)、8-DOP以及凸壳(CONVEX HULL)。

常见包容盒( Bounding Volumes)分类:

  • 包容球:SPHERE 用球体包围整个几何体,用于相交测试很方便,但是其紧密型差,周围空隙较大,当物体变形后,包围球需要重新计算。当对象进行旋转运动时,包围球不需要做任何更新,这是包围球的优势,即当几何对象频繁进行旋转运动时,使用包围球效率较高。
  • AABB包容盒:Axially Aligned Bounding Box,3D环境下的AABB盒即一个六面体,每个边都平行于一个坐标平面,较简单,但紧密性较差,当物体旋转、形变之后需要对AABB进行更新。本身的长宽高根据物体大小而定。
  • OBB包容盒:Oriented Bounding Box,此方法紧密型较好,可以降低参与相交测试的包容盒数目,因此性能要优于AABB和包容球。当物体发生旋转,仅需对OBB进行相同的旋转即可,但是当物体形变后,更新OBB的代价较大,故不适用那些软体的对象。
  • 8-DOP:8-DOP是由八个平面构成的。每个平面都与其他七个平面相交,形成一个闭合的多边形。这些平面可以通过基于物体的最小和最大坐标值来计算。也就是说,对于给定的物体,可以找到其最小和最大的X、Y和Z坐标值,并使用这些值来计算八个平面。8-DOP可以用于快速估计物体的包围盒,以便进行碰撞检测等操作。由于它是使用八个面来近似包围物体的,因此可能不够精确,但通常能提供一个较好的近似结果。它在某些情况下比其他简单的包围体(如轴对齐AABB包围盒)更有效,因为它可以更好地适应物体的形状。
  • 凸壳(CONVEX HULL):凸壳(Convex Hull)是指包含一组点集的最小凸多边形或凸体。在三维空间中,凸壳是一个封闭的、由凸面构成的立体结构。给定一组三维点,凸壳可以用来估计点云的整体形状,并提供一种紧凑的表示形式。计算凸壳的算法有很多种,其中著名的算法包括:Graham扫描算法:基于极角排序的凸壳计算算法。Jarvis march算法(也称为Gift Wrapping算法):通过不断选择点集中的最外层点来计算凸壳。QuickHull算法:利用分治法的思想,递归地划分空间以计算凸壳。3D Incremental算法:从一个简单的初始凸壳开始,逐步添加点以构建凸壳。

        如上图所示,越靠右,包容效果好、越紧密。但是检测速度更慢,也更消耗内存资源。 

代码实现 

#include <vector>
#include <thread>
#include <pcl/features/moment_of_inertia_estimation.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>using namespace std::chrono_literals;int main(int argc, char** argv)
{pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);// 从文件读取点云图pcl::PCDReader reader;reader.read("G:/vsdata/PCLlearn/PCDdata/bun0.pcd", *cloud);// 创建惯性矩估算对象,设置输入点云,并进行计算pcl::MomentOfInertiaEstimation <pcl::PointXYZ> feature_extractor;feature_extractor.setInputCloud(cloud);feature_extractor.compute();std::vector <float> moment_of_inertia;std::vector <float> eccentricity;pcl::PointXYZ min_point_AABB;pcl::PointXYZ max_point_AABB;pcl::PointXYZ min_point_OBB;pcl::PointXYZ max_point_OBB;pcl::PointXYZ position_OBB;Eigen::Matrix3f rotational_matrix_OBB;float major_value, middle_value, minor_value;Eigen::Vector3f major_vector, middle_vector, minor_vector;Eigen::Vector3f mass_center;// 获取惯性矩feature_extractor.getMomentOfInertia(moment_of_inertia);// 获取离心率feature_extractor.getEccentricity(eccentricity);// 获取AABB盒子feature_extractor.getAABB(min_point_AABB, max_point_AABB);// 获取OBB盒子feature_extractor.getOBB(min_point_OBB, max_point_OBB, position_OBB, rotational_matrix_OBB);feature_extractor.getEigenValues(major_value, middle_value, minor_value);// 获取主轴major_vector,中轴middle_vector,辅助轴minor_vectorfeature_extractor.getEigenVectors(major_vector, middle_vector, minor_vector);// 获取质心feature_extractor.getMassCenter(mass_center);pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));viewer->setBackgroundColor(0, 0, 0);viewer->addCoordinateSystem(1.0);viewer->initCameraParameters();viewer->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud");// 添加AABB包容盒viewer->addCube(min_point_AABB.x, max_point_AABB.x, min_point_AABB.y, max_point_AABB.y, min_point_AABB.z, max_point_AABB.z, 1.0, 1.0, 0.0, "AABB");viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "AABB");// 添加OBB包容盒Eigen::Vector3f position(position_OBB.x, position_OBB.y, position_OBB.z);Eigen::Quaternionf quat(rotational_matrix_OBB);// position:中心位置// quat:旋转矩阵// max_point_OBB.x - min_point_OBB.x  宽度// max_point_OBB.y - min_point_OBB.y  高度// max_point_OBB.z - min_point_OBB.z  深度viewer->addCube(position, quat, max_point_OBB.x - min_point_OBB.x, max_point_OBB.y - min_point_OBB.y, max_point_OBB.z - min_point_OBB.z, "OBB");viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "OBB");pcl::PointXYZ center(mass_center(0), mass_center(1), mass_center(2));pcl::PointXYZ x_axis(major_vector(0) + mass_center(0), major_vector(1) + mass_center(1), major_vector(2) + mass_center(2));pcl::PointXYZ y_axis(middle_vector(0) + mass_center(0), middle_vector(1) + mass_center(1), middle_vector(2) + mass_center(2));pcl::PointXYZ z_axis(minor_vector(0) + mass_center(0), minor_vector(1) + mass_center(1), minor_vector(2) + mass_center(2));viewer->addLine(center, x_axis, 1.0f, 0.0f, 0.0f, "major eigen vector");viewer->addLine(center, y_axis, 0.0f, 1.0f, 0.0f, "middle eigen vector");viewer->addLine(center, z_axis, 0.0f, 0.0f, 1.0f, "minor eigen vector");while (!viewer->wasStopped()){viewer->spinOnce(10);std::this_thread::sleep_for(10ms);}return (0);
}

实现效果

        黄色立方体为AABB包容盒,白色立方体为OBB包容盒。 

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

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

相关文章

为什么说CDN是网站速度优化大师

CDN&#xff08;内容分发网络&#xff09;是一个强大的工具&#xff0c;可以帮助您的网站实现飞一般的加载速度。本文将引领您深入了解CDN的奇妙世界&#xff0c;揭示其强大功能&#xff0c;并提供关于如何充分利用CDN服务来提升网站性能的宝贵建议。 探索CDN的世界 CDN&#x…

主从Reactor高并发服务器

文章目录 Reactor模型的典型分类单Reactor单线程单Reactor多线程多Reactor多线程本项目中实现的主从Reactor One Thread One Loop各模型的优点与缺点 项目分解Reactor服务器模块BufferSocketChannelEpollerTimerWheelEventLoopAnyConnectionAcceptorLoopThreadLoopThreadPoolTc…

根据前序遍历结果构造二叉搜索树

根据前序遍历结果构造二叉搜索树-力扣 1008 题 题目说明&#xff1a; 1.preorder 长度>1 2.preorder 没有重复值 直接插入 解题思路&#xff1a; 数组索引[0]的位置为根节点&#xff0c;与根节点开始比较&#xff0c;比根节点小的就往左边插&#xff0c;比根节点大的就往右…

AI如何帮助Salesforce从业者找工作?

在当今竞争激烈的就业市场中&#xff0c;找到满意的工作是一项艰巨的任务。成千上万的候选人竞争一个岗位&#xff0c;你需要利用一切优势从求职大军中脱颖而出。 这就是AI的用武之地&#xff0c;特别是像ChatGPT这样的人工智能工具&#xff0c;可以成为你的秘密武器。本篇文章…

知识图谱系列4:neo4j学习

这是一篇还不错的教程&#xff0c;我将会针对其中的Cypher语法在这篇帖子内提出问题&#xff0c;以便学习与复习。 MATCH是什么操作&#xff1f; 小括号()代表什么&#xff1f;&#xff08;n&#xff09;代表什么&#xff1f; MATCH (n) DETACH DELETE n是什么含义&#xff1…

使用poi-tl循环导出word报表

先看模板和导出的效果 模板 效果 根据模板循环生成表格&#xff0c;每个表格再循环填充数据&#xff0c;也就是两层循环&#xff0c;第一层循环是学生学期信息&#xff0c;第二层循环是学生的成绩数据。 第一个循环 {{?listTable}} {{/}}第二个循环 {{reportList}} 表格…

【深度学习实验】循环神经网络(二):使用循环神经网络(RNN)模型进行序列数据的预测

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. RNN模型 a. 初始化__init__ b. 前向传播方法forward 2. 训练和预测 a. 超参数 b. 创建模型实例 c. 模型训练 d. 预测结果可视化 3. 代码整合 经验是智慧之父…

磁盘满了对日志打印(Logback)的影响

背景 我们生产环境有一个服务半夜报警&#xff1a;磁盘剩余空间不足10%&#xff0c;请及时处理。排查后发现是新上线的一个功能&#xff0c;日志打太多导致的&#xff0c;解决方法有很多&#xff0c;就不赘述了。领导担心报警不及时、或者报警遗漏&#xff0c;担心磁盘满了对线…

【Monorepo实战】pnpm+turbo+vitepress构建公共组件库文档系统

Monorepo架构可以把多个独立的系统放到一起联调&#xff0c;本文记录基于pnpm > workspace功能&#xff0c;如何构建将vitepress和组件库进行联调&#xff0c;并且使用turbo进行任务顺序编排。 技术栈清单&#xff1a; pnpm 、vitepress 、turbo 一、需求分析 1、最终目标…

“高级Vue状态管理 - Vuex的魅力与应用“

目录 引言1. Vuex的简介1.1 什么是Vuex&#xff1f;1.2 Vuex的核心概念 2. Vuex的值获取与改变(综合案例)3. Vuex的异步请求总结 引言 在现代Web开发中&#xff0c;前端应用变得越来越复杂。随着应用规模的扩大和数据流的复杂性增加&#xff0c;有效地管理应用的状态成为了一项…

澳大利亚教育部宣布ChatGPT将被允许在澳学校使用!

教育部长最近宣布&#xff0c;从 2024 年起&#xff0c;包括 ChatGPT 在内的人工智能将被允许在所有澳大利亚学校使用。 &#xff08;图片来源&#xff1a;卫报&#xff09; 而早些时候&#xff0c;澳洲各高校就已经在寻找与Chatgpt之间的平衡了。 之前&#xff0c;悉尼大学就…

【例题】逆波兰表达式求值(图解+代码)

【例题】逆波兰表达式求值(图解代码) 这里写目录标题 【例题】逆波兰表达式求值(图解代码)逆波兰表达式解释优点转换计算代码 题目描述 : 逆波兰表示法是一种将运算符&#xff08;operator&#xff09;写在操作数&#xff08;operand&#xff09;后面的描述程序&#xff08;算式…

java过滤非中英文的特殊字符,四字节表情字符

过滤非中英文的特殊字符 /*** 过滤特殊字符* param str str* return String*/ public static String filterStr(String str) {if (StringUtils.isBlank(str)) {return str;}String regEx "[~!#$%^&*()|{}:;,\\[\\].<>/?~&#xff01;#&#xffe5;%……&…

Android---Synchronized 和 ReentrantLock

Synchronized 基本使用 1. 修饰实例方法 public class SynchronizedMethods{private int sum 0;public synchronized void calculate(){sum sum 1;} } 这种情况下的锁对象是当前实例对象&#xff0c;因此只有同一个实例对象调用此方法才会产生互斥效果&#xff1b;不同的…

Jenkins 添加节点Node报错JNI error has occurred UnsupportedClassVersionError

节点日志 报错信息如下 Error: A JNI error has occurred, please check your installation and try again Exception in thread “main” java.lang.UnsupportedClassVersionError: hudson/remoting/Launcher has been compiled by a more recent version of the Java Runtime…

LeetCode【300】最长递增子序列

题目&#xff1a; 思路&#xff1a; 通常来说&#xff0c;子序列不要求连续&#xff0c;而子数组或子字符串必须连续&#xff1b;对于子序列问题&#xff0c;第一种动态规划方法是&#xff0c;定义 dp 数组&#xff0c;其中 dp[i] 表示以 i 结尾的子序列的性质。在处理好每个…

vue3+ts项目02-安装eslint、prettier和sass

创建项目 项目创建 安装eslint yarn add eslint -D生成配置文件 npx eslint --init安装其他插件 yarn add -D eslint-plugin-import eslint-plugin-vue eslint-plugin-node eslint-plugin-prettier eslint-config-prettier eslint-plugin-node babel/eslint-parser vue-e…

关于IDEA中gradle项目bootrun无法进入断点以及gradle配置页面不全的解决方案

问题背景 在使用gradle编写的bootrun&#xff0c;采用debug方式启动项目时&#xff0c;无法进入断点&#xff0c;程序正常运行 并发现象1 此处无法识别为大象图标 点击右键后&#xff0c;没有圈中的这个选项 并发现象2 图片圈中的位置缺失 问题原因 正常的 run 命令是通过…

小程序, 多选项

小程序, 多选项 <view class"my-filter-btnwrap"><block wx:for"{{archiveList}}" wx:key"index"><view class"my-filter-btnitem text-ellipsis {{item.checked ? active : }}" data-index"{{index}}" wx…

CTF 全讲解:[SWPUCTF 2021 新生赛]Do_you_know_http

文章目录 参考环境题目hello.php雾现User-Agent伪造 User-AgentHackBarHackBar 插件的获取修改请求头信息 雾散 a.php雾现本地回环地址与客户端 IP 相关的 HTTP 请求头X-Forwarded-For 雾散 参考 项目描述搜索引擎Bing、GoogleAI 大模型文心一言、通义千问、讯飞星火认知大模型…