首页 > 编程语言 >稀疏八叉树算法(SVO)示例

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

时间:2024-10-23 14:20:59浏览次数:1  
标签:SVO min max 八叉树 示例 mid 节点 bounds self

稀疏八叉树算法示例:

from matplotlib import pyplot as plt
import numpy as np

class 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) / 2
        mid_y = (y_min + y_max) / 2
        mid_z = (z_min + z_max) / 2

        sub_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:
            return

        for point in self.points:
            for child in self.children:
                if child.contains_point(point):
                    child.points.append(point)
                    break

        self.points = []  # 清空当前节点的点,所有点已分配到子节点

    # 检查点是否在节点的边界内
    def contains_point(self, point):
        x, y, z = point
        x_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 = 6

class 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.points
        self._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()

  效果如下:

 

 

标签:SVO,min,max,八叉树,示例,mid,节点,bounds,self
From: https://www.cnblogs.com/hxqmw/p/18496299

相关文章

  • 【八叉树】从上千万个物体中【**瞬间**】就近选取坐标
    众里寻他千百度,蓦然回首,那人却在灯火阑珊处前情提要在某些情况下,我们在场景中创建了数百万个物体,这些物体没有直接的网格或碰撞体(例如,通过GPU绘制的物体),因此无法通过常规的射线检测与碰撞体进行交互。我们仅掌握这些物体的坐标或顶点位置。在这种情况下,我们该如何通过鼠标来......
  • .NET 8 Web API从基础到提高全面示例
    .NET8WebAPI从基础到提高全面示例 概述:1.设置.NET8WebAPI项目概念使用.NETCLI创建新的WebAPI项目。这设置了一个基本的项目结构,包括启动和WeatherForecast控制器作为示例。Program.cs代码示例dotnetnewwebapi-nMyWebApi2.Program.cs—最低限度的API......
  • PHP发票验真 API-发票真伪查验、验证接口示例
    发票验真API是一种在线服务,它允许用户或企业通过编程接口(API)验证发票的真实性。这种服务通常由政府机构或者授权的第三方(如翔云、百度)提供,旨在打击伪造发票的行为,保护消费者的合法权益,同时也有助于税务机关加强税收管理。企业和个人可以通过发票查验API接口来验证增值税......
  • 低功耗4G模组:tcs3472颜色传感器示例
    ​今天我们学习合宙低功耗4G模组Air780EP的LuatOS开发tcs3472示例,文末【阅读原文】获取最新资料1一、简介tcs3472颜色传感器能够读取照射到的物体的RGB三种数值,从而识别颜色关联文档和使用工具:LuatOS固件获取tcs3472颜色传感器接口说明Luatools下载调试工具二......
  • 低功耗4G模组:LCD应用示例
    ​今天我们学习合宙Air780E开发板LCD应用示例,文末【阅读原文】获取最新资料。本文档适用于Air780E开发板关联文档和使用工具lcd-demo:https://gitee.com/openLuat/LuatOS/tree/master/demo/lcdLuatools下载调试工具一、环境准备1.1Air780E开发板一套 ​1.......
  • flutter的custompaint组件示例6
    这段代码是一个Flutter应用程序,它创建了一个动态的艺术效果,其中包含随机颜色的点在屏幕上不断更新位置。import'package:flutter/material.dart';import'dart:math';voidmain(){runApp(MyApp());}classMyAppextendsStatelessWidget{@overrideWidget......
  • flutter的custompaint组件示例5
    这段代码是一个简单的Flutter应用程序,它创建了一个可拖动的自定义圆角矩形组件。import'package:flutter/material.dart';voidmain(){runApp(MyApp());}classMyAppextendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){return......
  • SpringBoot + Activiti工作流项目示例(源码)
    前言activiti工作流引擎项目,企业erp、oa、hr、crm等企事业办公系统轻松落地,一套完整并且实际运用在多套项目中的案例,满足日常业务流程审批需求。一、项目形式springboot+vue+activiti集成了activiti在线编辑器,流行的前后端分离部署开发模式,快速开发平台,可插拔工作流服务。工......
  • AOP - Advisor 示例
    定义通知publicclassLoggingAdviceimplementsMethodInterceptor{@OverridepublicObjectinvoke(MethodInvocationinvocation)throwsThrowable{System.out.println("Method"+invocation.getMethod().getName()+"isbeingcalle......
  • AOP - AspectJ 示例
    //自定义注解@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public@interfaceLogExecution{}@Aspect//切面类@Order(1000)//数字越小,优先级越高@Component//也要注册到容器publicclassLoggingAspect{//定义切点@Pointcut("ex......