空间管理 详解八叉树

空间管理 详解八叉树

  • 前言
  • 1.数据结构选型
    • 1.1数组
    • 1.2树型结构
    • 1.3哈希线性结构
  • 2.查询
    • 2.1 Morton位置码
      • 2.1.1 Morton码计算
      • 2.1.2 位置与Morton码的映射
      • 2.1.3 代码中的运算
        • 2.1.3.1 按位分离
        • 2.1.3.2 交叉组合
  • 3.插入
  • 4.删除
  • 5.碰撞检测
    • 5.2 避免多次检测

前言

首先先明确一个概念,八叉树只做空间管理,而碰撞相关的检测是另外的东西
空间管理 详解八叉树_第1张图片

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位置码

空间管理 详解八叉树_第2张图片
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平面的右侧

次有效高位可以判断是在子节点中的左右,因为每次都是原先的二分之一。
空间管理 详解八叉树_第3张图片
空间管理 详解八叉树_第4张图片

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.

序号 符号 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1
①<<16 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
①^② 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
③&④ 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
序号 符号 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
①<<8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
①^② 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1
③&④ 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1
序号 符号 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1
①<<4 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0
①^② 1 1 0 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1
③&④ 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1
序号 符号 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1
①<<2 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0
①^② 0 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1
0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1
③&④ 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1

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 避免多次检测

//未完待续

你可能感兴趣的:(图形学)