空间划分的数据结构(网格/四叉树/八叉树/BSP树/k-d树/BVH/自定义划分)

目录

  • 网格 (Grid)
    • 网格的应用
  • 四叉树/八叉树 (Quadtree/Octree)
    • 四叉树/八叉树的应用
  • BSP树 (Binary Space Partitioning Tree)
    • 判断点在平面前后算法
    • BSP树的应用
    • 参考
  • k-d树 (k-dimensional tree)
    • k-d树的构建
    • k-d树的应用
    • 参考
  • 层次包围盒树 (Bounding Volume Hierarchy Based On Tree)
    • 层次包围盒树的应用
    • 参考
  • 自定义区域
    • 判断点是否在凸多边形区域算法
    • 自定义区域划分的应用

前言:
在游戏程序中,空间划分往往是非常重要的优化思想。
于是博主花了一些时间去整理了游戏程序中常用的几个空间划分数据结构,并将它们大概列举出来以供笔记。

网格 (Grid)

这个很容易理解,即一个多维数组。平面/基于高度的空间使用二维网格数组,而3D空间使用三维网格数组。

Data girds2d[MAX_X][MAX_Y];//2D平面划分网格,二维数组
Data girds3d[MAX_X][MAX_Y][MAX_Z];//3D空间划分网格,三维数组

网格的应用

  • 基于网格划分的游戏世界

例如战棋/棋类游戏,Minecraft方块游戏等。

空间划分的数据结构(网格/四叉树/八叉树/BSP树/k-d树/BVH/自定义划分)_第1张图片


四叉树/八叉树 (Quadtree/Octree)

空间划分的数据结构(网格/四叉树/八叉树/BSP树/k-d树/BVH/自定义划分)_第2张图片

四叉树索引的基本思想是将地理空间递归划分为不同层次的树结构。
它将已知范围的空间等分成四个相等的子空间,如此递归下去,直至树的层次达到一定深度或者满足某种要求后停止分割。

空间划分的数据结构(网格/四叉树/八叉树/BSP树/k-d树/BVH/自定义划分)_第3张图片

//示例:一个四叉树节点的简单结构
struct QuadtreeNode {
  Data data;
  QuadtreeNode* children[2][2];
  int divide;  //表示这个区域的划分长度
};
//示例:找到x,y位置对应的四叉树节点
QuadTreeNode* findNode(int x,int y,QuadtreeNode * root){
  if(!root)return;

  QuadtreeNode* node = root;
  
  for(int i = 0; i < N && n; ++i){
    //通过diliver来将x,y归纳为0或1的值,从而索引到对应的子节点。
    int divide = node->divide;
    int divideX = x / divide;
    int divideY = y / divide;
    
    QuadtreeNode* temp = node->children[divideX][divideY];
    if(!temp){break;}
    node = temp;
    
    //如果归纳为1的值,还需要减去该划分长度,以便进一步划分
    x -= (divideX == 1 ? divide : 0);
    y -= (divideY == 1 ? divide : 0);
  }
  
  return node;
}

四叉树的结构在空间数据对象分布比较均匀时,具有比较高的空间数据插入和查询效率(复杂度O(logN))。

空间划分的数据结构(网格/四叉树/八叉树/BSP树/k-d树/BVH/自定义划分)_第4张图片

而八叉树的结构和四叉树基本类似,其拥有8个节点(三维2元素数组),其构建方法与查询方法也大同小异,不多描述。

四叉树/八叉树的应用<

你可能感兴趣的:(数据结构与算法,java,游戏)