四叉树

空间索引 - 四叉树

 ̄綄美尐妖づ 提交于 2020-03-22 11:39:10
/*--> */ /*--> */ /*--> */ /*--> */ /*--> */ /*--> */ 前言 作为程序员,应该都对二叉树都不陌生,我们都知道二叉树的变体二叉查找树,非常适合用来进行对一维数列的存储和查找,可以达到 O(logn) 的效率;我们在用二叉查找树进行插入数据时,根据一个数据的值和树结点值的对比,选择二叉树的两个叉之一向下,直到叶子结点,查找时使用二分法也可以迅速找到需要的数据。 但二叉树只支持一维数据,如一个标量数值,对地图上的位置点这种有xy两个方向上的信息却无能为力,那么是否有一种树能够支持二维数据的快速查询呢? 四叉树 介绍 四元树又称四叉树是一种树状数据结构,在每一个节点上会有四个子区块。四元树常应用于二维空间数据的分析与分类。它将数据区分成为四个象限。 今天要介绍的四叉树可以认为是二叉查找树的高维变体,它适合对有二维属性的数据进行存储和查询,当然四叉树存储的也不一定是二维数据,而是有着二维属性的数据,如有着 x,y 信息的点,用它还可以用来存储线和面数据。它有四个 叉 ,在数据插入时,我们通过其二维属性(一般是 x,y)选择四个叉之一继续向下,直至叶子结点,同样使用“四分法”来迅速查找数据。四叉树的一般图形结构如下: 聪明的小伙伴一定想到了适合存储和查询三维数据的八叉树,它们原理是一致的,不过我们暂不讨论。 分类 四叉树常见的应用有图像处理

四叉树空间索引原理及其实现

自古美人都是妖i 提交于 2020-03-22 11:37:40
转自原文 四叉树空间索引原理及其实现 四叉树索引的基本思想是将地理空间递归划分为不同层次的树结构。它将已知范围的空间等分成四个相等的子空间,如此递归下去,直至树的层次达到一定深度或者满足某种要求后停止分割。四叉树的结构比较简单,并且当空间数据对象分布比较均匀时,具有比较高的空间数据插入和查询效率,因此四叉树是GIS中常用的空间索引之一。常规四叉树的结构如图所示,地理空间对象都存储在叶子节点上,中间节点以及根节点不存储地理空间对象。 四叉树示意图 四叉树对于区域查询,效率比较高。但如果空间对象分布不均匀,随着地理空间对象的不断插入,四叉树的层次会不断地加深,将形成一棵严重不平衡的四叉树,那么每次查询的深度将大大的增多,从而导致查询效率的急剧下降。 本节将介绍一种改进的四叉树索引结构。四叉树结构是自顶向下逐步划分的一种树状的层次结构。传统的四叉树索引存在着以下几个缺点: (1)空间实体只能存储在叶子节点中,中间节点以及根节点不能存储空间实体信息,随着空间对象的不断插入,最终会导致四叉树树的层次比较深,在进行空间数据窗口查询的时候效率会比较低下。 (2)同一个地理实体在四叉树的分裂过程中极有可能存储在多个节点中,这样就导致了索引存储空间的浪费。 (3)由于地理空间对象可能分布不均衡,这样会导致常规四叉树生成一棵极为不平衡的树,这样也会造成树结构的不平衡以及存储空间的浪费。 相应的改进方法

[翻译]XNA 3.0 Game Programming Recipes之six

梦想的初衷 提交于 2020-03-22 11:35:33
PS:自己翻译的,转载请著明出处 2-10.使用一个四叉树隐藏部分网格是看不到的 问题 地形绘制是创建一个游戏一个最基本的部分。然而,这个方法在5-8也有描述,你建立一个巨大的地形可能不会注意到祯速率下降。 解决方案 用四叉树您可以减轻大地形渲染工作量。这是一个类似八叉树,因为你将你的地形划分成较小的方格,直到所有这些方格 不超过指定的大小。 就象在图表2-13中左边看到的进程。A16*16方格被分裂成4个方格,它们然后又被分成4个方格。 这个方式的好处是等你准备绘制地形时,只需要绘制在摄象机视阈中的方格就可以了。你要做到这一点,就靠方格与摄象机的可视范围碰撞测出。 正如图表2-13右半部所示,这些方格在应该灰色被绘制出来。 四叉树是一个简化版本的八叉树。四叉树需要划分为四个只规模较小的方格,而八叉树节点需要分为八个子立方体。一个八叉树也需要跟踪在它里面 所有对象的位置。但是四叉数不需要做这些。 如何工作的 建立一个新类,它是一个方格,四叉树的一个节点。 1 namespace BookCode 2 { 3 class OTNode 4 { 5 private BoundingBox nodeBoundingBox; 6 private bool isEndNode; 7 private QTNode nodeUL; 8 private QTNode nodeUR; 9

UVA - 11297 Census (树套树/四叉树)

人走茶凉 提交于 2020-03-01 21:09:27
题目链接 二维平面RMQ问题,单点修改,区间询问最大最小值 树套树或者四叉树均可做 树套树版本: 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=500+10,mod=1e9+7,inf=0x3f3f3f3f; 5 int n,Q,a[N][N]; 6 struct D {int mx,mi;} tr[N<<2][N<<2]; 7 D operator+(const D& a,const D& b) {return {max(a.mx,b.mx),min(a.mi,b.mi)};} 8 #define ls(u) (u<<1) 9 #define rs(u) (u<<1|1) 10 #define mid ((l+r)>>1) 11 void pu(int U,int u) {tr[U][u]=tr[U][ls(u)]+tr[U][rs(u)];} 12 D qry2(int U,int y1,int y2,int u=1,int l=1,int r=n) { 13 if(l>=y1&&r<=y2)return tr[U][u]; 14 if(l>y2||r<y1)return {~inf,inf}; 15 return qry2(U,y1,y2,ls(u)

python 实现 四叉树(二维平面进行管理的)

我的梦境 提交于 2020-02-18 21:40:48
# -*- coding: utf-8 -*- ''' @author: zou_albert ''' import pdb class Node ( ) : # 普通节点 反复调用 def __init__ ( self , parent , options , pos_num ) : ## pos_num 代表子节点的那个方位的数字 self . depth = parent . depth + 1 # if (self.depth >= options.tree_deep - 1): # # print "ERROR!!!! Maximum depth exceeded" # exit() # pdb.set_trace() self . parent_id = 0 self . is_leaf = 0 # 是否是叶节点呢 暂时可能不用 self . is_root = 0 self . parent = parent # 父母节点 # if 1 > 0: # print "zoujunboq" deltax = ( parent . xmax - parent . xmin ) / 2 deltay = ( parent . ymax - parent . ymin ) / 2 # if(self.depth == options.tree_deep - 1):

栅格数据的编码方法

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-22 22:57:36
直接栅格编码 直接编码就是将栅格数据看作一个数据矩阵, 逐行(或逐列)逐个记录代码 ,可以每行从左到右逐像元记录,也可奇数行从左到右而偶数行由右向左记录,为了特定的目的还可采用其他特殊的顺序。 链式编码 链式编码又称为弗里曼链码(Freeman,1961)或边界链码。 链式编码主要是记录线状地物和面状地物的边界。 它把线状地物和面状地物的边界表示为:由某一起始点开始并按某些基本方向确定的单位矢量链。基本方向可定义为:东=0,东南=l,南=2,西南=3,西=4,西北=5,北=6,东北=7等八个基本方向。 链式编码的前两个数字表示起点的行、列数,从第三个数字开始的每个数字表示单位矢量的方向,八个方向以0—7的整数代表。 链式编码对线状和多边形的表示具有很强的数据压缩能力,且具有一定的运算功能,如面积和周长计算等,探测边界急弯和凹进部分等都比较容易,类似矢量数据结构,比较适于存储图形数据。 缺点是对叠置运算如组合、相交等则很难实施,对局部修改将改变整体结构,效率较低,而且由于链码以每个区域为单位存储边界,相邻区域的边界则被重复存储而产生冗余。 游程长度编码 游程长度编码是栅格数据压缩的重要编码方法,它的基本思路是:对于一幅栅格图像,常常有行(或列)方向上相邻的若干点具有相同的属性代码,因而可采取某种方法压缩那些重复的记录内容。其编码方案是,只在各行(或列

unity 四叉树管理场景

眉间皱痕 提交于 2019-11-26 20:29:11
声明:参考 https://blog.csdn.net/mobilebbki399/article/details/79491544 和《游戏编程模式》 当场景元素过多时,需要实时的显示及隐藏物体使得性能提示,但是物体那么多,怎么知道哪些物体需要显示,哪些物体不需要显示的。当然,遍历物体判断该物体是否可以显示是最容易想到的方法,但是每次更新要遍历所有物体的代价很高,有没有其他可以替代的方法呢,当然有,四叉树就是其中一个方法。 假设场景是一维的,所有物体从左到右排成一条线,那么用二分法就可以快速找出距离自己一定范围内的物体。 同样四叉树的原理像二分一样,只是二分法处理的是一维世界, 四叉树处理的是二维世界,再往上三维世界用八叉树处理,这里用四叉树管理,八叉树暂时不讨论,原理类似。 这里先展示效果: 四叉树结构: 根节点是整个场景区域,然后分成四块:左上右上左下右下,分别作为根节点的儿子,然后每个儿子又分成四块重复之前步骤,这就是一棵四叉树。 每个节点保存四个儿子节点的引用,并且有存放在自己节点的物体列表,为什么物体不全部存放在叶子节点呢?因为有可能某个物体比较大,刚好在两个块的边界上。 这时候有两种做法: 1、这个物体同时插入两个节点的物体列表中 2、这个物体放在两个几点的父亲节点的物体列表中 第一种方法管理起来比较麻烦,所以在此采用第二种方法。 首先定义场景物体的数据类: 1