空间管理 详解八叉树

前言

首先先明确一个概念,八叉树只做空间管理,而碰撞相关的检测是另外的东西
在这里插入图片描述

1.数据结构选型

1.1数组

需要为完全树,比较不灵活,内存占用较大

1.2树型结构

可以不为完全树,深度不一,需要再扩展,节省内存,搜索数据的复杂度为 O ( l o g n ) O(logn) O(logn)

1.3哈希线性结构

通过哈希表存储,散列处理比较麻烦,但是搜索的复杂度为 O ( 1 ) O(1) O(1),并且使用Morton码作为键值时,有很好的占位率

2.查询

2.1 Morton位置码

在这里插入图片描述
Morton码是通过一定的编码方式,将空间上的位置通过Z字形管理起来。

2.1.1 Morton码计算

将行数和列数的2进制交叉组合,可以得到位置码

为什么要交叉组合:因为Morton码的增加是通过每行增加两位后,再进入下一行的

例子:
第3行第4列:
3的二进制表示:011
4的二进制表示:100
交叉组合:011010

2.1.2 位置与Morton码的映射

假设x轴向上的八叉树范围为 [ x m i n , x m a x ] [x_{min},x_{max}] [xmin,xmax],八叉树半径为r,则
位置码 p = x − x m i n 2 ∗ r p=\frac{x-x_{min}}{2*r} p=2rxxmin
p<0.5则数位于yz平面的左侧,为0
p>0.5则数位于yz平面的右侧,为1
将其转换为二进制,有效高位为0,则在yz平面的左侧
将其转换为二进制,有效高位为1,则在yz平面的右侧

次有效高位可以判断是在子节点中的左右,因为每次都是原先的二分之一。
在这里插入图片描述
在这里插入图片描述

2.1.3 代码中的运算

2.1.3.1 按位分离
    UInt32 Part1By2(UInt32 n)
    {
        n = (n ^ (n << 16)) & 0xff0000ff; //1
        n = (n ^ (n << 8)) & 0x0300f00f;//2
        n = (n ^ (n << 4)) & 0x030c30c3;//3
        n = (n ^ (n << 2)) & 0x09249249;//4
        return n;
    }

若使用UInt32作为存储,因为xyz需要三位,则最多存10组数据
32÷3=10······2
1.

序号符号313029282726252423222120191817161514131211109876543210
00000000000000000000001111111111
①<<1600000011111111110000000000000000
①^②00000011111111110000001111111111
11111111000000000000000011111111
③&④00000011000000000000000011111111
序号符号313029282726252423222120191817161514131211109876543210
00000011000000000000000011111111
①<<800000000000000001111111100000000
①^②00000011000000001111111111111111
00000011000000001111000000001111
③&④00000011000000001111000000001111
序号符号313029282726252423222120191817161514131211109876543210
00000011000000001111000000001111
①<<411000000000011110000000011110000
①^②11000011000011111111000011111111
00000011000011000011000011000011
③&④00000011000011000011000011000011
序号符号313029282726252423222120191817161514131211109876543210
00000011000011000011000011000011
①<<200001100001100001100001100001100
①^②00001111001111001111001111001111
00001001001001001001001001001001
③&④00001001001001001001001001001001
2.1.3.2 交叉组合
    UInt32 Morton3(UInt32 x, UInt32 y, UInt32 z)
    {
        return (Part1By2(z) << 2) + (Part1By2(y) << 1) + Part1By2(x);
    }

3.插入

//未完待续

4.删除

//未完待续

5.碰撞检测

5.2 避免多次检测

//未完待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值