松散八叉树

article/2025/10/28 23:30:29
  • 1八叉树简述
    • 1.1定义
    • 1.2数据
    • 1.3树的建立
      • 1.3.1计算包围体的大小与中心点
      • 1.3.2判断物体所属的包围盒
  • 2松散八叉树
    • 2.1松散八叉树的建立

八叉树简述

定义

八叉树是一种对三维世界进行场景管理的理想的空间数据结构。八叉树中根节点包含一个立方体包围盒。每个非叶子节点都拥有八个子节点,它们将双亲节点细分为八分体。也就是说而且每个子节点表示一个立方体的体积元素,而且所有子节点的体积加起来是父节点的体积。
当满足用户所定义的标准被满足时,停止细分。常见的停止标准有:

  • 节点包围盒达到一个特定大小
  • 节点内包含的多边形数目达到最小数目

 

 

数据

八叉树的每个节点至少要包含以下数据:

  • 包围盒 — 空间中的八叉树节点所包含的封闭立方体
  • 几何体列表 — 包含在该节点内的所包含的几何体
  • 子节点 — 指向每个子节点的指针
  • 相邻节点 — 每个节点最多有六个相邻节点(立方体拥有六个平面)。在碰撞检测的过程中,对八叉树的遍历要求指向相邻节点的指针。

树的建立

包含多边形数目大于最低阈值POLY_THRESHOLD的节点,BuildOctree()会产生8个子节点。BuildNode()函数创建了节点数据,主要包含两个步骤:

  • 为节点创建包围盒(通过父节点的包围盒确定宽度、高度以及深度,并通过索引i确定包围盒的中心位置是8个子节点中的哪一个)
  • 确定哪些多边形位于节点的包围盒内部

 

BuildOctree(Node N) { if(NumPolys(N)>POLY_THRESHOLD) for(int i = 0; i < 8; i++) { BuildNode(N->Child[i], i, N); BuildOctree(N->Child[i]); } }

1

2

3

4

5

6

7

8

9

10

11

BuildOctree(Node N)

{

  if(NumPolys(N)>POLY_THRESHOLD)

     for(int i = 0; i < 8; i++)

     {

       BuildNode(N->Child[i], i, N);

       BuildOctree(N->Child[i]);

     }

 

}

 

 

计算包围体的大小与中心点

某层节点立方体包围盒的边长计算公式:

L(depth)=W/(2depth)

 

某层节点与其相邻节点包围盒中心间距的计算公式:

S(depth)=W/(2depth)

 

W:worldsize

 

depth:depth(root)=0

 

判断物体所属的包围盒

伪代码如下:

struct node{ vector3 CubeCenter; node* Child[2][2][2]; ObjectList Objects; }; int Classify(plane p,volume v){ if(v is completely behind p){ return 0; }else if(v is completely in front of p){ return 1; }else{ // v straddles p. return 2; } } void InsertObjectIntoTree(node* n,Object* o){ int xc = Classify(plane(1,0,0,CubeCenter.x)),o.BoundingVolume); int yc = Classify(plane(0,1,0,CubeCenter.y)),o.BoundingVolume); int zc = Classify(plane(0,0,1,CubeCenter.z)),o.BoundingVolume); if(xc ==2 || yc == 2 || zc == 2) { //Object straddles one pr more of the child partition planes, //and so won't fit in any child node,so store it in this node. Objects.Insert(o) }else{ //Object fits in one of the child nodes.Recurse to find the //correct descendant. InsertObjectIntoTree(Child[zc][yc][xc],o) } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

struct node{

   vector3 CubeCenter;

   node*   Child[2][2][2];

   ObjectList Objects;

};

 

int Classify(plane p,volume v){

  if(v is completely behind p){

     return 0;

  }else if(v is completely in front of p){

     return 1;

  }else{

     // v straddles p.

     return 2;

  }

}

 

void InsertObjectIntoTree(node* n,Object* o){

  int xc = Classify(plane(1,0,0,CubeCenter.x)),o.BoundingVolume);

  int yc = Classify(plane(0,1,0,CubeCenter.y)),o.BoundingVolume);

  int zc = Classify(plane(0,0,1,CubeCenter.z)),o.BoundingVolume);

  if(xc ==2 || yc == 2 || zc == 2)

  {

    //Object straddles one pr more of the child partition planes,

    //and so won't fit in any child node,so store it in this node.

    Objects.Insert(o)

  }else{

    //Object fits in one of the child nodes.Recurse to find the

    //correct descendant.

    InsertObjectIntoTree(Child[zc][yc][xc],o)

  }

}

 

 

松散八叉树

八叉树是一种典型有效的空间数据结构。但是它有一些缺点:较小的物体可能因为其特殊位置被存储到一个具有非常大的包围盒体积的八叉树节点中。在《Game Programming Gems》中该问题被描述为层次划分过程中产生的“粘性(Sticky)”区域,较小的物体却保持在树的较高层次,降低了划分的效率。

松散八叉树的建立

松散八叉树的“松散”是指调整节点的包围体大小,“放松”包围立方体,但是同时节点的层次和节点的中心不变。在松散八叉树中,包围立方体边长的计算公式修改为:

L(depth)=k∗W/(2depth)

 

节点的间距依旧与传统八叉树保持一致。这意味着同层节点的包围立方体会相互重叠,如图c)所示。

松散八叉树

而k值的选择就是一个比较重要的问题,k值过小则无法体现松散八叉树减少粘性区域的优势,k值过大则会导致包围体过于松散。各类文献中基本都建议选择k=2,能够获得最好的效果。

假设一棵松散八叉树的k=2,我们可以计算出节点所在的深度,而物体在那一层深度中的哪个位置则取决于物体中心位置的坐标。

层次选择公式的推导过程:


已知深度的情况下,只需要选择距离物体中心最近的节点就可以确定物体应该被哪个节点的包围盒所包含。

index[x,y,z]=floor(object.[x,y,z]+W/2)/S(depth))


http://chatgpt.dhexx.cn/article/cbX8cxDf.shtml

相关文章

八叉树学习

八叉树学习 八叉树结构八叉树的存储结构1. 规则八叉树&#xff1a;2.线性八叉树&#xff1a;3.一对八式八叉树 参考网站 八叉树结构 八叉树结构是由 Hunter 博士于1978年首次提出的一种数据模型。八叉树结构通过对三维空间的几何实体进行体元剖分&#xff0c;每个体元具有相同…

PCL中的八叉树

目录 &#xff08;1&#xff09;什么是八叉树 &#xff08;2&#xff09;PCL中八叉树的体素形成和PCL中基于八叉树的点云压缩 &#xff08;3&#xff09;基于八叉树的k邻域搜索、半径搜索和体素近邻搜索 &#xff08;4&#xff09;基于八叉树和基于 kd-tree 的k邻域搜索、半…

八叉树 java_java简单实现八叉树图像处理代码示例

一晃工作有段时间了&#xff0c;第一次写博客&#xff0c;有点不知道怎么写&#xff0c;大家将就着看吧&#xff0c;说的有什么不正确的也请大家指正。 最近工作中用到了一个图像压缩的功能。找了一些工具&#xff0c;没有太好的选择。最后选了一个叫jdeli的&#xff0c;奈何效…

八叉树

http://hi.baidu.com/onlywater/blog/item/905c5e162ed18f4021a4e9c1.html 一、八叉树基本原理&#xff1a; 用八叉树来表示三维形体&#xff0c;并研究这种表示下的各种操作以及应用&#xff0c;是进入80年代后开展起来的。这种方法&#xff0c;既可以看成是四叉树方法在三维…

Octree(八叉树)

1. 算法原理 八叉树&#xff08;Octree&#xff09;是一种用于描述三维空间的树状数据结构。八叉树的每个节点表示一个正方体的体积元素&#xff0c;每个节点有八个子节点&#xff0c;将八个子节点所表示的体积元素加在一起就等于父节点的体积。八叉树是四叉树在三维空间上的扩…

【PCL自学:ocTree】八叉树(octree)的原理及应用案例(点云压缩,搜索,空间变化)

PCL中八叉树&#xff08;octree&#xff09;的原理及应用案例 一、什么是八叉树ocTree&#xff1f;1.八叉树原理 二、八叉树应用案例1.点云压缩2.用八叉树进行空间划分和搜索操作3.无序点云数据的空间变化检测 一、什么是八叉树ocTree&#xff1f; 1.八叉树原理 上世纪80年代&…

十进制小数化为二进制小数的方法是什么_十进制转成二进制的两种方式

第一种&#xff1a;用2整除的方式。 用2整除十进制整数&#xff0c;得到一个商和余数&#xff1b;再用2去除商&#xff0c;又会得到一个商和余数&#xff0c;如此重复&#xff0c;直到商为小于1时为止&#xff0c;然后把先得到余数作为二进制数的低位有效位&#xff0c;后得到的…

Python 利用内置函数把二进制小数转换为十进制

如果需要把一个二进制整数转换为十进制整数&#xff0c;只需要简单的一行&#xff1a; int(1101,2) 但如果有一个二进制小数的话&#xff0c;就需要自己实现一个函数了。 不过&#xff0c;许多人是这样写的&#xff1a;(图片取自这里) 可是&#xff0c;由于python本身并不适…

[学习笔记] 二进制小数表示方法

文章目录 科学计数法二进制推广计算机中的小数EXCESS表示系统特殊情况举例&#xff08;float&#xff09;普通情况最大正实数普通情况最小负实数普通情况最小正实数特殊情况最大正实数 科学计数法 科学计数法想必大家都很熟悉了&#xff0c;往往通过如下形式表示一个实数&…

十进制小数化为二进制小数的方法是什么_二进制的转换

二进制是在计算机中常用的一种进制数&#xff0c;其数据用0和1两个数码来表示数据。我们人类常用的是十进制&#xff0c;那么二进制和十进制之间是有一个转换方法的。 二进制转换十进制 一个二进制数转换为十进制数&#xff0c;是比较简单的&#xff0c;其方法就是用每一个位置…

二进制小数的意义

回忆小学学的十进制小数的意义&#xff1a; 15.23这个小数&#xff0c;1是十位&#xff0c;5是个位&#xff0c;2是十分位&#xff0c;3是百分位。这个小数的意义为&#xff1a;&#xff0c;因为最低位为百分位&#xff0c;所以分母是100。 小数末尾加上0或去掉0&#xff0c;小…

浮点数(小数)在计算机中如何用二进制存储?

浮点数在计算机中如何用二进制存储&#xff1f; 前言 前面我有篇博文详解了二进制数&#xff0c;以及如何同二进制数表示整数。但是&#xff0c;计算机处理的不仅仅是整数&#xff0c;还有小数&#xff0c;同样小数在计算机也是用二进制进行存储的&#xff0c;但是&#xff0…

二进制小数的表示

二级制小数分为两大类&#xff1a;1、定点数&#xff1b;2、浮点数。 定点数 定点数&#xff1a; &#xff08;1&#xff09;小数点位置固定不变的数。 &#xff08;2&#xff09;定点数有定点整数和定点小数。 &#xff08;定点整数&#xff1a;小数部分为0&#xff1b;定点…

腾讯TDSQL全时态数据库系统论文入选VLDB

当地时间2019年8月26至30日&#xff0c;VLDB 2019会议在美国加利福尼亚召开&#xff0c;腾讯分布式数据库TDSQL与中国人民大学最新联合研究成果被VLDB 2019接收并将通过长文形式发表。VLDB是国际数据管理与数据库领域顶尖的学术会议之一&#xff0c;这是继去年腾讯TDSQL相似度计…

顶会VLDB‘22论文解读:CAE-ENSEMBLE算法

摘要&#xff1a;针对时间序列离群点检测问题&#xff0c;提出了基于CNN-AutoEncoder和集成学习的CAE-ENSEMBLE深度神经网络算法&#xff0c;并通过大量的实验证明CAE-ENSEMBLE算法能有效提高时间序列离群点检测的准确度与效率。 本文分享自华为云社区《VLDB22 CAE-ENSEMBLE论文…

【轨迹压缩】Trajectory Simplification: On Minimizing the Direction-based Error [2015] [VLDB]

一、一个动机 保护方向信息的方向保持轨迹简化&#xff08;DPTS&#xff09;已被证明表现良好&#xff0c;而现有关于 DPTS 的研究 要求用户指定一个容错&#xff0c;在某些情况下用户可能不知道如何正确设置&#xff08;例如&#xff0c;容错只能在未来某个时间知道&#xff…

VLDB 2021 EAB最佳论文:深度解析机器学习的基数估计为何无法实现?

©作者 | 曲昌博单位 | 西蒙菲莎大学近日&#xff0c;IEEE 数据工程新星奖王健楠团队论文《Are We Ready for Learned Cardinality Estimation?》夺得数据库顶会 VLDB 2021 年度的 EA&B 最佳论文奖。 数据库是企业管理和查询数据的复杂软件系统。 近年来随着机器学习以…

Transformers如何处理表格数据?【VLDB2022教程】Transformer表格数据表示:模型和应用...

来源&#xff1a;专知 本文为教程介绍&#xff0c;建议阅读5分钟最近的研究工作通过开发表格数据的神经表示扩展了语言模型。 在过去的几年中&#xff0c;自然语言处理界见证了基于transformer的语言模型(LM)在自由文本的神经表示方面的进展。鉴于关系表中可用知识的重要性&…

openGauss亮相VLDB2020,展示内存优化研究成果

VLDB&#xff08;Very Large Data Base&#xff09;作为数据库领域的三大顶级国际会议之一&#xff0c;是面向数据库研究人员&#xff0c;内核开发人员&#xff0c;开发商以及用户的年度国际会议论坛&#xff0c;代表数据库系统领域最杰出的研究和工程进展。在2020年&#xff0…

VLDB 2023 | 北大河图发布分布式训练神器Galvatron,一键实现大模型高效自动并行...

©作者 | 北京大学河图团队 单位 | 北京大学数据与智能实验室 北大河图团队提出了一套面向大模型的自动并行分布式训练系统 Galvatron&#xff0c;相比于现有工作在多样性、复杂性、实用性方面均具有显著优势&#xff0c;论文成果已经被 VLDB 2023 接收。 最近一段时间&…