http://blog.csdn.net/pizi0475/article/details/6269060
四叉树或四元树也被称为Q树(Q-Tree)。四叉树广泛应用于图像处理、空间数据索引、2D中的快速碰撞检测、存储稀疏数据等,而八叉树(Octree)主要应用于3D图形处理。
实际的数据结构,就是一个树根不断地往下扩,每次分成八个枝,直到叶子为止。
叶子节点代表了分辨率最高的情况。例如分辨率设成0.01m,那么每个叶子就是一个1cm见方的小方块
#include <iostream>
using namespace std;
template<class T>
struct OctreeNode
T data;
T xMin, xMax;
T yMin, yMax;
T zMin, zMax;
OctreeNode <T> *top_left_front, *top_left_back;
OctreeNode <T> *top_right_front, *top_right_back;
OctreeNode <T> *bottom_left_front, *bottom_left_back;
OctreeNode <T> *bottom_right_front, *bottom_right_back;
OctreeNode
(T nodeValue = T(),
T xminValue = T(), T xmaxValue = T(),
T yminValue = T(), T ymaxValue = T(),
T zminValue = T(), T zmaxValue = T(),
OctreeNode<T>* top_left_front_Node = NULL,
OctreeNode<T>* top_left_back_Node = NULL,
OctreeNode<T>* top_right_front_Node = NULL,
OctreeNode<T>* top_right_back_Node = NULL,
OctreeNode<T>* bottom_left_front_Node = NULL,
OctreeNode<T>* bottom_left_back_Node = NULL,
OctreeNode<T>* bottom_right_front_Node = NULL,
OctreeNode<T>* bottom_right_back_Node = NULL)
: data(nodeValue),
xMin(xminValue), xMax(xmaxValue),
yMin(yminValue), yMax(ymaxValue),
zMin(zminValue), zMax(zmaxValue),
top_left_front(top_left_front_Node),
top_left_back(top_left_back_Node),
top_right_front(top_right_front_Node),
top_right_back(top_right_back_Node),
bottom_left_front(bottom_left_front_Node),
bottom_left_back(bottom_left_back_Node),
bottom_right_front(bottom_right_front_Node),
bottom_right_back(bottom_right_back_Node) {}
template <class T>
void createOctree(OctreeNode<T> * &root, int maxdepth, double xMin, double xMax, double yMin, double yMax, double zMin, double zMax)
cout << "处理中,请稍候……" << endl;
maxdepth = maxdepth - 1;
if (maxdepth >= 0)
root = new OctreeNode<T>();
root->data = 9;
root->xMin = xMin;
root->xMax = xMax;
root->yMin = yMin;
root->yMax = yMax;
root->zMin = zMin;
root->zMax = zMax;
double xMind = (xMax - xMin) / 2;
double yMind = (yMax - yMin) / 2;
double zMind = (zMax - zMin) / 2;
createOctree(root->top_left_front, maxdepth, xMin, xMax - xMind, yMax - yMind, yMax, zMax - zMind, zMax);
createOctree(root->top_left_back, maxdepth, xMin, xMax - xMind, yMin, yMax - yMind, zMax - zMind, zMax);
createOctree(root->top_right_front, maxdepth, xMax - xMind, xMax, yMax - yMind, yMax, zMax - zMind, zMax);
createOctree(root->top_right_back, maxdepth, xMax - xMind, xMax, yMin, yMax - yMind, zMax - zMind, zMax);
createOctree(root->bottom_left_front, maxdepth, xMin, xMax - xMind, yMax - yMind, yMax, zMin, zMax - zMind);
createOctree(root->bottom_left_back, maxdepth, xMin, xMax - xMind, yMin, yMax - yMind, zMin, zMax - zMind);
createOctree(root->bottom_right_front, maxdepth, xMax - xMind, xMax, yMax - yMind, yMax, zMin, zMax - zMind);
createOctree(root->bottom_right_back, maxdepth, xMax - xMind, xMax, yMin, yMax - yMind, zMin, zMax - zMind);
int i = 1;
template <class T>
void preOrder(OctreeNode<T> * & p)
if (p)
cout << i << ".当前节点的值为:" << p->data << "\n坐标为:";
cout << " xMin: " << p->xMin << " xMax: " << p->xMax;
cout << " yMin: " << p->yMin << " yMax: " << p->yMax;
cout << " zMin: " << p->zMin << " zMax: " << p->zMax;
i += 1;
cout << endl;
preOrder(p->top_left_front);
preOrder(p->top_left_back);
preOrder(p->top_right_front);
preOrder(p->top_right_back);
preOrder(p->bottom_left_front);
preOrder(p->bottom_left_back);
preOrder(p->bottom_right_front);
preOrder(p->bottom_right_back);
cout << endl;
template<class T>
int depth(OctreeNode<T> *& p)
if (p == NULL)
return -1;
int h = depth(p->top_left_front);
return h + 1;
int cal(int num)
int result = 1;
if (1 == num)
result = 1;
for (int i = 1; i < num; i++)
result = 2 * result;
return result;
int maxdepth = 0;
int times = 0;
static double xMin = 0, xMax = 0, yMin = 0, yMax = 0, zMin = 0, zMax = 0;
int tmaxdepth = 0;
double txm = 1, tym = 1, tzm = 1;
template<class T>
void find(OctreeNode<T> *& p, double x, double y, double z)
double xMind = (p->xMax - p->xMin) / 2;
double yMind = (p->yMax - p->yMin) / 2;
double zMind = (p->yMax - p->yMin) / 2;
times++;
if (x > xMax || x<xMin || y>yMax || y<yMin || z>zMax || z < zMin)
cout << "该点不在场景中!" << endl;
return;
if (x <= p->xMin + txm && x >= p->xMax - txm && y <= p->yMin + tym &&
y >= p->yMax - tym && z <= p->zMin + tzm && z >= p->zMax - tzm)
cout << endl << "找到该点!" << "该点位于" << endl;
cout << " xMin: " << p->xMin << " xMax: " << p->xMax;
cout << " yMin: " << p->yMin << " yMax: " << p->yMax;
cout << " zMin: " << p->zMin << " zMax: " << p->zMax;
cout << "节点内!" << endl;
cout << "共经过" << times << "次递归!" << endl;
else if (x < (p->xMax - xMind) && y < (p->yMax - yMind) && z < (p->zMax - zMind))
cout << "当前经过节点坐标:" << endl;
cout << " xMin: " << p->xMin << " xMax: " << p->xMax;
cout << " yMin: " << p->yMin << " yMax: " << p->yMax;
cout << " zMin: " << p->zMin << " zMax: " << p->zMax;
cout << endl;
find(p->bottom_left_back, x, y, z);
else if (x < (p->xMax - xMind) && y<(p->yMax - yMind) && z>(p->zMax - zMind))
cout << "当前经过节点坐标:" << endl;
cout << " xMin: " << p->xMin << " xMax: " << p->xMax;
cout << " yMin: " << p->yMin << " yMax: " << p->yMax;
cout << " zMin: " << p->zMin << " zMax: " << p->zMax;
cout << endl;
find(p->top_left_back, x, y, z);
else if (x > (p->xMax - xMind) && y < (p->yMax - yMind) && z < (p->zMax - zMind))
cout << "当前经过节点坐标:" << endl;
cout << " xMin: " << p->xMin << " xMax: " << p->xMax;
cout << " yMin: " << p->yMin << " yMax: " << p->yMax;
cout << " zMin: " << p->zMin << " zMax: " << p->zMax;
cout << endl;
find(p->bottom_right_back, x, y, z);
else if (x > (p->xMax - xMind) && y<(p->yMax - yMind) && z>(p->zMax - zMind))
cout << "当前经过节点坐标:" << endl;
cout << " xMin: " << p->xMin << " xMax: " << p->xMax;
cout << " yMin: " << p->yMin << " yMax: " << p->yMax;
cout << " zMin: " << p->zMin << " zMax: " << p->zMax;
cout << endl;
find(p->top_right_back, x, y, z);
else if (x<(p->xMax - xMind) && y>(p->yMax - yMind) && z < (p->zMax - zMind))
cout << "当前经过节点坐标:" << endl;
cout << " xMin: " << p->xMin << " xMax: " << p->xMax;
cout << " yMin: " << p->yMin << " yMax: " << p->yMax;
cout << " zMin: " << p->zMin << " zMax: " << p->zMax;
cout << endl;
find(p->bottom_left_front, x, y, z);
else if (x<(p->xMax - xMind) && y>(p->yMax - yMind) && z > (p->zMax - zMind))
cout << "当前经过节点坐标:" << endl;
cout << " xMin: " << p->xMin << " xMax: " << p->xMax;
cout << " yMin: " << p->yMin << " yMax: " << p->yMax;
cout << " zMin: " << p->zMin << " zMax: " << p->zMax;
cout << endl;
find(p->top_left_front, x, y, z);
else if (x > (p->xMax - xMind) && y > (p->yMax - yMind) && z < (p->zMax - zMind))
cout << "当前经过节点坐标:" << endl;
cout << " xMin: " << p->xMin << " xMax: " << p->xMax;
cout << " yMin: " << p->yMin << " yMax: " << p->yMax;
cout << " zMin: " << p->zMin << " zMax: " << p->zMax;
cout << endl;
find(p->bottom_right_front, x, y, z);
else if (x > (p->xMax - xMind) && y > (p->yMax - yMind) && z > (p->zMax - zMind))
cout << "当前经过节点坐标:" << endl;
cout << " xMin: " << p->xMin << " xMax: " << p->xMax;
cout << " yMin: " << p->yMin << " yMax: " << p->yMax;
cout << " zMin: " << p->zMin << " zMax: " << p->zMax;
cout << endl;
find(p->top_right_front, x, y, z);
int main()
OctreeNode<double> * rootNode = NULL;
int choiced = 0;
while (true)
system("cls");
cout << "请选择操作:\n";
cout << "1.创建八叉树 2.先序遍历八叉树\n";
cout << "3.查看树深度 4.查找节点 \n";
cout << "0.退出\n\n";
cin >> choiced;
if (choiced == 0)
return 0;
else if (choiced == 1)
system("cls");
cout << "请输入最大递归深度:" << endl;
cin >> maxdepth;
cout << "请输入外包盒坐标,顺序如下:xMin,xMax,yMin,yMax,zMin,zMax" << endl;
cin >> xMin >> xMax >> yMin >> yMax >> zMin >> zMax;
if (maxdepth >= 0 || xMax > xMin || yMax > yMin || zMax > zMin || xMin > 0 || yMin > 0 || zMin > 0)
tmaxdepth = cal(maxdepth);
txm = (xMax - xMin) / tmaxdepth;
tym = (yMax - yMin) / tmaxdepth;
tzm = (zMax - zMin) / tmaxdepth;
createOctree(rootNode, maxdepth, xMin, xMax, yMin, yMax, zMin, zMax);
cout << "输入错误!";
return 0;
else if (choiced == 2)
system("cls");
cout << "先序遍历八叉树结果:\n";
i = 1;
preOrder(rootNode);
cout << endl;
system("pause");
else if (choiced == 3)
system("cls");
int dep = depth(rootNode);
cout << "此八叉树的深度为" << dep + 1 << endl;
system("pause");
else if (choiced == 4)
system("cls");
cout << "请输入您希望查找的点的坐标,顺序如下:x,y,z\n";
double x, y, z;
cin >> x >> y >> z;
times = 0;
cout << endl << "开始搜寻该点……" << endl;
find(rootNode, x, y, z);
system("pause");
system("cls");
cout << "\n\n错误选择!\n";
system("pause");
http://blog.csdn.net/pizi0475/article/details/6269060四叉树或四元树也被称为Q树(Q-Tree)。四叉树广泛应用于图像处理、空间数据索引、2D中的快速碰撞检测、存储稀疏数据等,而八叉树(Octree)主要应用于3D图形处理。实际的数据结构,就是一个树根不断地往下扩,每次分成八个枝,直到叶子为止。 叶子节点代表了分辨率最高的情况。例如分辨率设成0.
建立空间索引在点云数据处理中已被广泛应用,常见空间索引一般是自顶向下逐级划分空间的各种空间索引结构:BSP树、k-d tree、KDB树、R树、R+树、CELL树、四叉树、八叉树等。
k-d tree对于区间和近邻搜索十分有用。
PCL中k-d tree 库提供了k-d tree数据结构,基于FLANN进行快速最近邻检索。最近邻检
八叉树删减算法的一些思考以及c++实现
文章目录八叉树删减算法的一些思考以及c++实现前言一、为什么要减色处理?二、思路分析1.如何用八叉树表示所有颜色2.如何插入一个新的颜色3.如何合并元素代码分析1.节点结构总结
这几天上多媒体技术这门课,老师布置了八叉树删减算法的作业,简单谈谈自己的一点想法。
一、为什么要减色处理?
位图采用RGB颜色模型,是一个二维的像素矩阵的方法显示和存储的图象,矩阵中的每个元素代表一个像素。但是如果直接用这个矩阵表示每一种颜色,就会导致图片很大(R、G、B各八位,共有
八叉树这块的代码,在别人的基础上,把有问题的地方稍作改动,以及不懂得地方多加了注释,当作以后的学习资料。
#include <iostream>
using namespace std;
//定义八叉树节点类
template<class T>
struct OctreeNode
T data; //节点数据
T xmin, xmax; //节点坐标,即六面体个顶点的坐标
T ymin, ymax;
T zmin, zmax;
OctreeNode <
八叉树图片
八叉树(octree),或称八元树,是一种用于描述三维空间(划分空间)的树状数据结构。八叉树的每个节点表示一个正方体的体积元素,每个节点有八个子节点,这八个子节点所表示的体积元素加在一起就等于父节点的体积。一般中心点作为节点的分叉中心。
•三维计算机图形
•最邻近搜索
import { Vector3 } from "math-ds" ;
import { PointOctree } from "sparse-octree" ;
const min = new Vector3 ( - 1 , - 1 , - 1 ) ;
const max = new Vector3 ( 1 , 1 , 1 ) ;
const octree = new PointOctree ( min , max ) ;
const myData = { } ;
const p1 = new Vector3 ( 0 , 0 , 0 ) ;
const p2 = new Vector3 ( 0 , 0 , 0.5 ) ;
octree . insert ( p1 , myData ) ;
octree . move ( p1 , p2 ) ;
octree . get ( p2 ) ; //
好的,我可以帮你写一段用于生成八叉树图片的 C 代码。首先,你需要了解八叉树的算法原理并准备好所需的图片处理库(例如,使用C语言时可以使用GD库)。
在你的C代码中,你需要定义一个函数用于绘制八叉树,该函数需要几个参数:
- 图像的宽度和高度
- 图像的中心位置的 x 坐标和 y 坐标
- 八叉树的深度
- 八叉树边的颜色
例如,你可以使用以下函数声明来绘制八叉树:
void drawOctree(int width, int height, int centerX, int centerY, int depth, color c);
在函数内部,你需要使用图像处理库的函数将八叉树的边绘制到图像上。例如,在GD库中,可以使用`gdImageLine()`函数在图像上绘制直线。
你可以使用递归来绘制八叉树。在每次递归中,你需要计算新的中心位置,并调用`drawOctree()`函数绘制八叉树的八个子节点。你可以使用以下代码段来实现这一点:
if (depth > 0) {
int newWidth = width / 2;
int newHeight = height / 2;
drawOctree(newWidth, newHeight, centerX - newWidth / 2, centerY - newHeight / 2, depth - 1, c);
drawOctree(newWidth, newHeight, centerX - newWidth / 2, centerY + newHeight / 2, depth - 1, c);
drawOctree(newWidth, newHeight, centerX
稍许笨拙:
Qt显示WAV音频文件的波形图/频谱图
罗801:
Windows 10下,OpenCV4 与 contribute 一起编译,第三方库无法下载的解决方案
子儒670:
Windows 10下,OpenCV4 与 contribute 一起编译,第三方库无法下载的解决方案
子儒670:
MFC单文档结构,实现OpenGL的绘图,移动,旋转,缩放
花米生的饭: