八叉树 C++ 基础 源码
来源:互联网 发布:steam mac dota2 编辑:程序博客网 时间:2024/05/30 23:50
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; //每递归一次就将最大递归深度-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; else { 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); }}//main函数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); } else { 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"); } else { system("cls"); cout << "\n\n错误选择!\n"; system("pause"); } }}
阅读全文
0 0
- c语言基础试题源码
- 八叉树 C++ 基础 源码
- 【基础C&C++】内存拷贝strcpy,memcpy,memmove,strncpy源码
- 基础c字符串相关函数的源码实现
- Python源码剖析笔记0 ——C语言基础
- Nginx源码分析 - 基础数据结构篇 - 内存池 ngx_palloc.c
- Nginx源码分析 - 基础数据结构篇 - 数组结构 ngx_array.c
- Nginx源码分析 - 基础数据结构篇 - 缓冲区结构 ngx_buf.c
- Nginx源码分析 - 基础数据结构篇 - 字符串结构 ngx_string.c
- C++/C源码分析
- C #基础
- c基础
- C基础
- c基础
- C 基础
- c基础
- C基础
- c基础
- Ubuntu与ROS的Docker桌面系统与ROS在线练习课程(在线Linux虚拟机)
- 基于的朴素贝叶斯的文本分类(附完整代码(spark/java)
- oracle索引详解
- OpenCV笔记(三)加载、显示图像
- Ubuntu14.04 安装 Sublime Text 3 及常用插件推荐
- 八叉树 C++ 基础 源码
- oracle---常用操作
- Android6.0动态权限的处理
- 三角函数公式推导
- !
- Android五大组件-Fragment
- 最新ps cs6序列号 永久免费可用
- Fluent Python笔记二
- 分布式存储系统设计(1)—— 系统架构