八叉树的实现
来源:互联网 发布:h5页面制作工具 知乎 编辑:程序博客网 时间:2024/05/16 19:33
八叉树的实现
2008-11-29 17:30 1455人阅读 评论(1) 收藏 举报
systemnull存储
- //Date : 2008/05/01
- //Filename : octree.cpp
- //Platform : VC++ 2005
- //八叉树的实现
- //功能:
- //1、创建八叉树。
- //此八叉树为满树,即所有节点/叶子全部创建。
- //用户可以自定义此八叉树的深度和所处的三维场景中的位置。
- //注a:由于创建树时为满树创建,故层数太大时创建时间可能会比较久,请耐心等待。
- //注b:创建顺序为(1)上层左前节点-(2)上层右前节点-(3)上层右前节点-(4)上层右后节点
- //-(5)下层左前节点-(6)下层右前节点-(7)下层右前节点-(8)下层右后节点-(1)-(2)……
- //2、先序遍历八叉树。
- //八叉树创建成功后用户可调用此子模块查看此八叉树,会显示每个结点的编号,值和在场景中的坐标。
- //3、查看八叉树的深度。
- //4、在场景中查找点。
- //用户首先输入要查找的坐标。
- //如果该点位于场景外则提示用户并返回,否则在场景中递归查找该点。
- //找到后输出该点所处的子结点的坐标和递归次数。
- #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 xm=(xmax-xmin)/2;//计算节点个维度上的半边长
- double ym=(ymax-ymin)/2;
- double zm=(ymax-ymin)/2;
- //递归创建子树,根据每一个节点所处(是几号节点)的位置决定其子结点的坐标。
- createOctree(root->top_left_front,maxdepth,xmin,xmax-xm,ymax-ym,ymax,zmax-zm,zmax);
- createOctree(root->top_left_back,maxdepth,xmin,xmax-xm,ymin,ymax-ym,zmax-zm,zmax);
- createOctree(root->top_right_front,maxdepth,xmax-xm,xmax,ymax-ym,ymax,zmax-zm,zmax);
- createOctree(root->top_right_back,maxdepth,xmax-xm,xmax,ymin,ymax-ym,zmax-zm,zmax);
- createOctree(root->bottom_left_front,maxdepth,xmin,xmax-xm,ymax-ym,ymax,zmin,zmax-zm);
- createOctree(root->bottom_left_back,maxdepth,xmin,xmax-xm,ymin,ymax-ym,zmin,zmax-zm);
- createOctree(root->bottom_right_front,maxdepth,xmax-xm,xmax,ymax-ym,ymax,zmin,zmax-zm);
- createOctree(root->bottom_right_back,maxdepth,xmax-xm,xmax,ymin,ymax-ym,zmin,zmax-zm);
- }
- }
- 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 xm=(p->xmax-p->xmin)/2;
- double ym=(p->ymax-p->ymin)/2;
- double zm=(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-xm) && y<(p->ymax-ym) && z<(p->zmax-zm))
- {
- 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-xm) && y<(p->ymax-ym) && z>(p->zmax-zm))
- {
- 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-xm) && y<(p->ymax-ym) && z<(p->zmax-zm))
- {
- 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-xm) && y<(p->ymax-ym) && z>(p->zmax-zm))
- {
- 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-xm) && y>(p->ymax-ym) && z<(p->zmax-zm))
- {
- 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-xm) && y>(p->ymax-ym) && z>(p->zmax-zm))
- {
- 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-xm) && y>(p->ymax-ym) && z<(p->zmax-zm))
- {
- 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-xm) && y>(p->ymax-ym) && z>(p->zmax-zm))
- {
- 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");
- }
- }
- }
- 八叉树的实现
- 八叉树的实现
- 八叉树的实现(转载)
- 三子棋的实现的实现的实现
- 八叉树图像处理的java简单实现
- JAVA实现的时钟实现
- 模态框的的实现
- 杀毒软件的简单实现的简单实现
- android的实现电话号码的实现
- 音频的实现音乐声音的实现
- malloc的实现、内存池的实现
- 八叉树及K-D树的应用和实现
- 八叉树及K-D树的应用和实现
- 八叉树及K-D树的应用和实现
- 八叉树及K-D树的应用和实现
- 八叉树及K-D树的应用和实现
- 异形窗体的实现
- 个性化的分页实现
- 电机控制PWM(MCPWM)
- 电路设计中的八大误区
- rst2pdf处理中文文档
- ERR_PTR,PTR_ERR还有IS_ERR函数详解
- 苹果Mac电脑会采用ARM芯片吗?
- 八叉树的实现
- 个人发展方面的计划
- C++笔试和面试题
- 解释执行和编译执行区别
- Linux英文版显示中文:local详解
- TC(SRM)和CF入门教程for ACMer
- Android Native层异步消息框架
- ArrayBlockingQueue源代码及解析
- JavaScript中的匿名函数及函数的闭包