添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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;
        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);
                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 &lt
八叉树图片 八叉树(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
稍许笨拙: 使用PushName的话,其实内存是布局是:命中的图元位于绘制顺序的第几个、最大Z、最小Z、ID(将选中的ID按顺序都加入(包括初始化的0))。 使用LoadName的话,内存布局:未知、最大Z、最小Z、命中的ID。 关于第一个未知,因为不管是命中一个还是同时命中两个,其第一个值一直为1 Qt显示WAV音频文件的波形图/频谱图 罗801: math.h的函数方法 Windows 10下,OpenCV4 与 contribute 一起编译,第三方库无法下载的解决方案 子儒670: 老哥,可以把你的下载文件给我一份吗? Windows 10下,OpenCV4 与 contribute 一起编译,第三方库无法下载的解决方案 子儒670: 我的下载不下啦啊,页面找不到 https://raw.githubusercontent.com/opencv/opencv_3rdparty/a56b6ac6f030c312b2dce17430eef13aed9af274/ippicv/ippicv_2020_win_intel64_20191018_general.zip MFC单文档结构,实现OpenGL的绘图,移动,旋转,缩放 花米生的饭: 这个鼠标移动功能不能同时使用吧