稀疏八叉树算法(SVO)示例

news/2024/10/23 14:35:35

稀疏八叉树算法示例:

from matplotlib import pyplot as plt
import numpy as npclass OctreeNode:def __init__(self, bounds, depth=0):self.bounds = bounds  # 体素的空间边界self.children = []  # 存储子节点self.depth = depth  # 当前节点的深度self.is_leaf = True  # 标记是否为叶节点self.points = []  # 存储在该节点内的点云数据# 判断是否需要细分节点def needs_subdivision(self, max_points):# 当节点中的点数超过最大限制且深度未超过最大深度时细分return len(self.points) > max_points and self.depth < OctreeNode.MAX_DEPTH# 细分节点,将其分成8个子节点def subdivide(self):x_min, y_min, z_min = self.bounds['min']x_max, y_max, z_max = self.bounds['max']mid_x = (x_min + x_max) / 2mid_y = (y_min + y_max) / 2mid_z = (z_min + z_max) / 2sub_bounds = [{'min': [x_min, y_min, z_min], 'max': [mid_x, mid_y, mid_z]},{'min': [mid_x, y_min, z_min], 'max': [x_max, mid_y, mid_z]},{'min': [x_min, mid_y, z_min], 'max': [mid_x, y_max, mid_z]},{'min': [mid_x, mid_y, z_min], 'max': [x_max, y_max, mid_z]},{'min': [x_min, y_min, mid_z], 'max': [mid_x, mid_y, z_max]},{'min': [mid_x, y_min, mid_z], 'max': [x_max, mid_y, z_max]},{'min': [x_min, mid_y, mid_z], 'max': [mid_x, y_max, z_max]},{'min': [mid_x, mid_y, mid_z], 'max': [x_max, y_max, z_max]},]for i in range(8):self.children.append(OctreeNode(sub_bounds[i], self.depth + 1))self.is_leaf = False  # 不再是叶节点# 分配点云到子节点def distribute_points(self):if self.is_leaf:returnfor point in self.points:for child in self.children:if child.contains_point(point):child.points.append(point)breakself.points = []  # 清空当前节点的点,所有点已分配到子节点# 检查点是否在节点的边界内def contains_point(self, point):x, y, z = pointx_min, y_min, z_min = self.bounds['min']x_max, y_max, z_max = self.bounds['max']return x_min <= x <= x_max and y_min <= y <= y_max and z_min <= z <= z_max# 定义 Octree 的最大深度
OctreeNode.MAX_DEPTH = 6class SVO:def __init__(self, points, bounds):self.root = OctreeNode(bounds)  # 根节点self.points = points  # 输入的点云数据def build_tree(self, max_points_per_node):self.root.points = self.pointsself._subdivide(self.root, max_points_per_node)def _subdivide(self, node, max_points_per_node):if node.needs_subdivision(max_points_per_node):node.subdivide()node.distribute_points()for child in node.children:self._subdivide(child, max_points_per_node)def traverse(self, callback):self._traverse_node(self.root, callback)def _traverse_node(self, node, callback):if node.is_leaf:callback(node)else:for child in node.children:self._traverse_node(child, callback)# 绘制框图
def draw_box(ax, min_corner, max_corner):# 绘制一个框图,min_corner和max_corner分别是框图的最小和最大点min_corner = np.array(min_corner)max_corner = np.array(max_corner)# 定义框图的8个顶点vertices = [min_corner,             # 0(min_corner[0], max_corner[1], min_corner[2]),  # 1(min_corner[0], min_corner[1], max_corner[2]),  # 2(min_corner[0], max_corner[1], max_corner[2]),  # 3(max_corner[0], min_corner[1], min_corner[2]),  # 4(max_corner[0], max_corner[1], min_corner[2]),  # 5(max_corner[0], min_corner[1], max_corner[2]),  # 6(max_corner[0], max_corner[1], max_corner[2]),  # 7]# 定义框图的12条边edges = [(0, 1), (1, 5), (5, 4), (4, 0),  # 底面(2, 3), (3, 7), (7, 6), (6, 2),  # 顶面(0, 2), (1, 3), (4, 6), (5, 7),  # 侧面]# 绘制框图的边for edge in edges:start_point = vertices[edge[0]]end_point = vertices[edge[1]]ax.plot([start_point[0], end_point[0]], [start_point[1], end_point[1]], [start_point[2], end_point[2]], 'k-')def callback(node):print(node.bounds)# 绘制边界框图draw_box(ax, node.bounds['min'], node.bounds['max'])print(node.points)# 绘制点
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')if __name__ == '__main__':points = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12],[13, 14, 15]]bounds = {'min': [-50, -50, -50], 'max': [50, 50, 50]}svo = SVO(points, bounds)svo.build_tree(2)svo.traverse(callback)ax.scatter(*zip(*points))# 绘制整个边界框图draw_box(ax, bounds['min'], bounds['max'])# 设置坐标轴的显示范围ax.set_xlim(-60, 60)ax.set_ylim(-60, 60)ax.set_zlim(-60, 60)# 显示图形plt.show()

  效果如下:

 

 

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

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

相关文章

腾讯课堂视频课件课程下载工具,如何在电脑端下载腾讯课堂视频课程课件资料到本地?

一. 安装腾讯课堂课程下载器 1.获取学无止下载器 https://www.xuewuzhi.cn/keqq_downloader 2.下载安装后,然后点击桌面快捷方式运行即可。 注意:杀毒软件可能会阻止外部exe文件运行,并将其当做成病毒,直接添加信任即可,本软件绝对没有木马病毒。 二. 使用说明 1.学无止下…

MySQL 回收表碎片实践教程

在 MySQL 数据库中,随着数据的增删改操作,表空间可能会出现碎片化,这不仅会占用额外的存储空间,还可能降低表的扫描效率,特别是一些大表,在进行数据清理后会产生大量的碎片。本篇文章我们一起来学习下如何进行碎片回收以及相关注意点。前言: 在 MySQL 数据库中,随着数据…

React实现画布——可绘制矩形和箭头

目录思路代码效果本文将使用React、JSX、Rough.js实现一个简单的画布,可以绘制矩形和箭头。思路每一个图形包括:绘制的类型、起点的x坐标、起点的y坐标、宽、高。调用rough的generator()函数传入图形信息进行绘制,其中对于箭头需要进一步处理:根据宽高确定终点,并且定义角…

使用URP后,unity内置渲染材质丢失解决

1.打开渲染管道转换器 2.选择built-in to URP,勾选下面所有选项,最后转换。

高途课堂视频课程资料下载工具,如何在电脑端下载高途和途途视频课程资料到本地?

一. 安装高途/途途课程下载器 1.获取学无止下载器 https://www.xuewuzhi.cn/gaotu_downloader 2.下载安装后,然后点击桌面快捷方式运行即可。 注意:杀毒软件可能会阻止外部exe文件运行,并将其当做成病毒,直接添加信任即可,本软件绝对没有木马病毒。 二. 使用说明 1.学无止…

在win10安装和使用wsl

WSL wsl(Windows Subsystem for Linux)是微软在Windows操作系统中引入的一个功能,它允许用户直接在Windows上运行Linux发行版的二进制可执行文件,而无需使用虚拟机或双启动系统。WSL提供了一个兼容层,使得Linux应用程序能够运行在Windows的内核上。wsl有以下特点:兼容性:…

Oracle认证证书的考试费用是多少

近期有学员咨询时问到:他大学学的是it和计算机方面的课程,在投简历时经常会看到Oracle认证优先,所以来问问Oracle证书的事情。 新接触数据库行业的毕业生或者转行的人可能不清楚Oracle认证的含金量,Oracle是非常有名的数据库产品,在db-ranking统计中,Oracle数据库一直霸占…

Nuxt.js 应用中的 builder:generateApp 事件钩子详解

title: Nuxt.js 应用中的 builder:generateApp 事件钩子详解 date: 2024/10/23 updated: 2024/10/23 author: cmdragon excerpt: builder:generateApp 是 Nuxt.js 的一个生命周期钩子,它在生成应用程序之前被调用。这个钩子为开发者提供了一个机会,可以在生成过程开始之前修…