c++ 三维图形 R树的简单应用案例

我们可以构建一个简单的应用案例,其中使用三维 R 树来存储和查询3D空间中的矩形包围盒(Bounding Boxes)。假设我们的应用场景是存储一些 3D 物体(如建筑、车辆、物品等)的空间位置,并根据查询范围来返回哪些物体与查询区域相交。

1.场景设定

假设我们有一个仓库管理系统,其中仓库中的物品被存储在三维空间中,我们将这些物品表示为 Box3D(三维矩形包围盒)。用户可以查询仓库中位于特定区域内的物品。

2.功能需求

  1. 插入物品:将物品(表示为三维矩形包围盒)插入到 R 树中。
  2. 范围查询:查询一个指定区域内的所有物品(即查询与给定范围相交的所有矩形包围盒)。

3.代码实现

以下是一个简单的三维 R 树应用案例,演示了如何存储物品的空间信息,并进行范围查询。

#include <iostream>
#include <vector>
#include <algorithm>// 定义三维矩形包围盒
struct Box3D {float x_min, y_min, z_min;float x_max, y_max, z_max;Box3D() : x_min(0), y_min(0), z_min(0), x_max(0), y_max(0), z_max(0) {}Box3D(float xmin, float ymin, float zmin, float xmax, float ymax, float zmax): x_min(xmin), y_min(ymin), z_min(zmin), x_max(xmax), y_max(ymax), z_max(zmax) {}// 合并两个三维矩形包围盒static Box3D merge(const Box3D& b1, const Box3D& b2) {return Box3D(std::min(b1.x_min, b2.x_min),std::min(b1.y_min, b2.y_min),std::min(b1.z_min, b2.z_min),std::max(b1.x_max, b2.x_max),std::max(b1.y_max, b2.y_max),std::max(b1.z_max, b2.z_max));}// 判断两个矩形包围盒是否相交bool intersects(const Box3D& other) const {return !(x_max < other.x_min || x_min > other.x_max ||y_max < other.y_min || y_min > other.y_max ||z_max < other.z_min || z_min > other.z_max);}// 输出包围盒信息void print() const {std::cout << "Box: (" << x_min << ", " << y_min << ", " << z_min << ") -> ("<< x_max << ", " << y_max << ", " << z_max << ")\n";}
};// R 树节点类
class RTreeNode {
public:bool is_leaf;  // 是否是叶子节点std::vector<RTreeNode*> children;  // 子节点std::vector<Box3D> entries;  // 节点中的矩形包围盒(或子节点)RTreeNode(bool leaf = false) : is_leaf(leaf) {}// 插入矩形包围盒到节点void insert(const Box3D& box) {entries.push_back(box);if (!is_leaf) {children.push_back(new RTreeNode(true));  // 简化,假设直接插入叶节点}}// 获取当前节点的包围盒(合并所有条目的包围盒)Box3D getBoundingBox() const {if (entries.empty()) return Box3D();Box3D bbox = entries[0];for (const auto& entry : entries) {bbox = Box3D::merge(bbox, entry);}return bbox;}// 递归查询相交的矩形包围盒void query(const Box3D& query_box, std::vector<Box3D>& result) const {// 检查当前节点的包围盒是否与查询框相交Box3D node_bbox = getBoundingBox();if (!node_bbox.intersects(query_box)) {return;  // 如果不相交,直接返回}// 如果是叶子节点,直接检查所有条目if (is_leaf) {for (const auto& entry : entries) {if (entry.intersects(query_box)) {result.push_back(entry);}}} else {// 递归查询子节点for (const auto& child : children) {child->query(query_box, result);}}}
};// 三维 R 树类
class RTree3D {
public:RTreeNode* root;size_t max_entries_per_node;RTree3D(size_t max_entries = 4) : max_entries_per_node(max_entries) {root = new RTreeNode(true);  // 创建根节点,假设为叶子节点}// 插入三维矩形包围盒void insert(const Box3D& box) {insert(root, box);}void insert(RTreeNode* node, const Box3D& box) {if (node->entries.size() < max_entries_per_node) {node->insert(box);} else {// 如果节点已满,进行分裂(这里采用简化的分裂方式)RTreeNode* new_node = new RTreeNode(true);new_node->insert(box);node->insert(box);  // 假设直接插入旧节点// 合并后,处理分裂策略(这里简化为直接插入)}}// 执行范围查询std::vector<Box3D> rangeQuery(const Box3D& query_box) {std::vector<Box3D> result;root->query(query_box, result);return result;}// 打印树结构(深度优先遍历)void printTree(RTreeNode* node, int depth = 0) {if (!node) return;for (int i = 0; i < depth; ++i) std::cout << "  ";std::cout << "Node (entries: " << node->entries.size() << ")\n";for (auto& entry : node->entries) {for (int i = 0; i < depth + 1; ++i) std::cout << "  ";std::cout << "  ";entry.print();}for (auto& child : node->children) {printTree(child, depth + 1);}}
};int main() {RTree3D tree;// 插入一些物品(三维矩形包围盒)tree.insert(Box3D(0, 0, 0, 5, 5, 5));tree.insert(Box3D(6, 6, 6, 10, 10, 10));tree.insert(Box3D(3, 3, 3, 8, 8, 8));tree.insert(Box3D(5, 5, 5, 7, 7, 7));// 打印树结构std::cout << "R-Tree Structure:\n";tree.printTree(tree.root);// 查询一个范围内的物品Box3D query_box(4, 4, 4, 9, 9, 9);  // 查询范围:从 (4,4,4) 到 (9,9,9)std::cout << "\nQuery Range: ";query_box.print();// 获取查询结果std::vector<Box3D> result = tree.rangeQuery(query_box);std::cout << "\nItems in query range:\n";for (const auto& box : result) {box.print();}return 0;
}

4.代码解释

  1. Box3D:定义了一个三维矩形包围盒,包含合并、相交判断等操作。
  2. RTreeNode
    • 包含 entries(矩形包围盒列表)和 children(子节点指针列表)。
    • query 方法用于递归查询与给定查询框相交的矩形包围盒。
  3. RTree3D
    • 提供 insert 方法来插入三维矩形包围盒。
    • rangeQuery 方法接受一个查询范围,返回所有与该范围相交的矩形包围盒。
  4. main
    • 插入一些示例物品(三维矩形包围盒)。
    • 执行范围查询,返回与查询范围相交的物品。

5.执行结果

输出树结构和查询结果。例如:

R-Tree Structure:
Node (entries: 2)Box: (0, 0, 

 

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

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

相关文章

LangChain构建行业知识库实践:从架构设计到生产部署全指南

文章目录 引言:行业知识库的进化挑战一、系统架构设计1.1 核心组件拓扑1.2 模块化设计原则二、关键技术实现2.1 文档预处理流水线2.2 混合检索增强三、领域适配优化3.1 医学知识图谱融合3.2 检索结果重排序算法四、生产环境部署4.1 性能优化方案4.2 安全防护体系五、评估与调优…

Lua的table(表)

Lua表的基本概念 Lua中的表&#xff08;table&#xff09;是一种多功能数据结构&#xff0c;可以用作数组、字典、集合等。表是Lua中唯一的数据结构机制&#xff0c;其他数据结构如数组、列表、队列等都可以通过表来实现。 表的实现 Lua的表由两部分组成&#xff1a; 数组部分…

应对现代生活的健康养生指南

在科技飞速发展的现代社会&#xff0c;人们的生活方式发生了巨大改变&#xff0c;随之而来的是一系列健康问题。快节奏的生活、高强度的工作以及电子产品的过度使用&#xff0c;让我们的身体承受着前所未有的压力。因此&#xff0c;掌握正确的健康养生方法迫在眉睫。 针对久坐不…

使用DeepSeek/chatgpt等AI工具辅助网络协议流量数据包分析

随着deepseek,chatgpt等大模型的能力越来越强大&#xff0c;本文将介绍一下deepseek等LLM在分数流量数据包这方面的能力。为需要借助LLM等大模型辅助分析流量数据包的同学提供参考&#xff0c;也了解一下目前是否有必要继续学习wireshark工具以及复杂的协议知识。 pcap格式 目…

【Linux】CentOS7停服之后配置yum镜像源

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 毛毛张今天分享一个CentOS7系统停服之后&#xff0c;配置yum镜像源的步骤&#xff0c;有坑&#xff01; 文章目录 1.概述2.查看系统架构2.1 查看内核版本2.2 查看lin…

2025-02-26 学习记录--C/C++-C语言 整数格式说明符

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; C语言 整数格式说明符 【例如 】&#x1f380; &#xff1a;在 C 语言中&#xff0c;%ld 是 printf 或 scanf 等格式化输入输出函…

OpenAI开放Deep Research权限,AI智能体大战升级,DeepSeek与Claude迎来新对决

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

个人电脑小参数GPT预训练、SFT、RLHF、蒸馏、CoT、Lora过程实践——MiniMind图文版教程

最近看到Github上开源了一个小模型的repo&#xff0c;是真正拉低LLM的学习门槛&#xff0c;让每个人都能从理解每一行代码&#xff0c; 从零开始亲手训练一个极小的语言模型。开源地址&#xff1a; GitHub - jingyaogong/minimind: &#x1f680;&#x1f680; 「大模型」2小时…

【数据结构】顺序表和链表

线性表 线性表 (linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串 ….. 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时…

一文讲解Redis的内存淘汰和过期策略

Redis 报内存不足怎么处理&#xff1f; Redis 内存不足有这么几种处理方式&#xff1a; 修改配置文件 redis.conf 的 maxmemory 参数&#xff0c;增加 Redis 可用内存 也可以通过命令 set maxmemory 动态设置内存上限 修改内存淘汰策略&#xff0c;及时释放内存空间 使用 R…

游戏引擎学习第125天

仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾并为今天的内容做准备。 昨天&#xff0c;当我们离开时&#xff0c;工作队列已经完成了基本的功能。这个队列虽然简单&#xff0c;但它能够执行任务&#xff0c;并且我们已经为各种操作编写了测试。字符串也能够正常推送到队…

【UCB CS 61B SP24】Lecture 16 - Data Structures 2: ADTs, BSTs学习笔记

本文首先介绍了抽象数据类型与树的概念&#xff0c;接着重点讲解二叉搜索树的定义与操作方式&#xff0c;并用 Java 实现一个标准的二叉搜索树结构。 1. 抽象数据类型 首先引入一个概念叫做抽象数据类型&#xff08;Abstract Data Type&#xff0c;ADT&#xff09;&#xff0…

包子凑数——蓝桥杯真题Python

包子凑数 输入输出样例 示例 1 输入 2 4 5输出 6样例说明 凑不出的数目包括&#xff1a;1, 2, 3, 6, 7, 11。 示例 2 输入 2 4 6输出 INF样例说明 所有奇数都凑不出来&#xff0c;所以有无限多个 运行限制 最大运行时间&#xff1a;1s最大运行内存: 256M 最大公约数 最大公…

一周学会Flask3 Python Web开发-Jinja2模版中加载静态文件

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 一个Web项目不仅需要HTML模板&#xff0c;还需要许多静态文件&#xff0c;比如 CSS、JavaScript文件、图片以及音频等。在Fla…

Python的那些事第三十二篇:用于创建静态、动画和交互式可视化的绘图库Matplotlib

Matplotlib:用于创建静态、动画和交互式可视化的绘图库 摘要 Matplotlib 是一个广泛使用的 Python 绘图库,能够创建静态、动画和交互式可视化图表。本文首先介绍了 Matplotlib 的基本功能和架构,然后通过具体的示例代码展示了如何使用 Matplotlib 创建不同类型的图表。接着…

tableau之雷达图和凹凸图

一、雷达图 概念 雷达图&#xff08;Radar Chart&#xff09;&#xff0c;也称为蜘蛛网图&#xff08;Spider Chart&#xff09;或星状图&#xff08;Star Chart&#xff09;&#xff0c;是一种用于多变量数据可视化的图表。它以中心点向外辐射的轴线表示不同的变量&#xff…

Redis-列表结构实操

列表实操 前言简单练习基本的LPUSH和RPUSH操作列表元素的访问与修改列表元素的插入和删除列表阻塞操作 困难练习分页列表游标机制业务上考虑直接访问任意页如何高效分页局限性小结 实现限时排行版轮换消息队列可靠性实现分布式锁实现 总结 前言 之前总结过-列表的数据结构,但是…

SpringBoot 2 后端通用开发模板搭建(异常处理,请求响应)

目录 一、环境准备 二、新建项目 三、整合依赖 1、MyBatis Plus 数据库操作 2、Hutool 工具库 3、Knife4j 接口文档 4、其他依赖 四、通用基础代码 1、自定义异常 2、响应包装类 3、全局异常处理器 4、请求包装类 5、全局跨域配置 补充&#xff1a;设置新建类/接…

实现Python+Django+Transformers库中的BertTokenizer和BertModel来进行BERT预训练,并将其应用于商品推荐功能

一、环境安装准备 #git拉取 bert-base-chinese 文件#创建 虚拟运行环境python -m venv myicrplatenv#刷新source myicrplatenv/bin/activate#python Django 集成nacospip install nacos-sdk-python#安装 Djangopip3 install Django5.1#安装 pymysql settings.py 里面需要 # 强制…

Rk3568驱动开发_点亮led灯代码完善(手动挡)_6

1.实现思路&#xff1a; 应用层打开设备后通过write函数向内核中写值&#xff0c;1代表要打开灯&#xff0c;0代表要关闭灯 Linux配置gpio和控制gpio多了一个虚拟内存映射操作 2.注意事项&#xff1a; 配置和读写操作的时候要谨慎&#xff0c;比如先关掉gpio再注销掉虚拟内存…