zoukankan      html  css  js  c++  java
  • 不规则八叉树的空间分割与检索

      不同规则八叉树,在每一次分割时,需要判断选择一个合适的分割维度(x或y或z),而不是每次都对xyz做分割。这样可以很大程度避免叶子节点为空的情况,检索起来速度也较快。但是叶子节点的形状不再是规则的正立方体,而是相互不等长方体。

     树的建立:

    int OcTree::buildOcTree() {
        ptree->root = new ocTreeNode;
        ptree->root->data = new size_t[pointsSize];
        for (size_t j = 0; j < pointsSize; j++)
        {
            ptree->root->data[j] = j;
        }
        
        ptree->root->numOfData = pointsSize;
        ptree->root->father = NULL;
        ptree->root->dim = 1;
        ptree->root->nodePos = 0;
    
        ocTreeNode* tempNode = ptree->root;
        std::queue<ocTreeNode*> octreeNodePtrQue;
        octreeNodePtrQue.push(tempNode);
        int slipnum = 0;
        float deltaNum = 0.0;
        //创建kdtree
        while (true)
        {
            //slipnum = tempkdnode->nodeDepth % 3;
            if (tempNode->numOfData==0)   //说明为空节点
            {
                octreeNodePtrQue.pop();
                if (octreeNodePtrQue.size() == 0)
                {
                    break;
                }
                tempNode = octreeNodePtrQue.front();
                continue;
            }
    
            //计算树的节点分割线
            float xtempMin = pointCloud[tempNode->data[0]].x;
            float ytempMin = pointCloud[tempNode->data[0]].y;
            float ztempMin = pointCloud[tempNode->data[0]].z;
            float xtempMax = xtempMin;
            float ytempMax = ytempMin;
            float ztempMax = ztempMin;
    
            for (size_t j = 0; j < tempNode->numOfData; j++)
            {
    
                if (xtempMin>pointCloud[tempNode->data[j]].x)
                {
                    xtempMin = pointCloud[tempNode->data[j]].x;
                }
                if (xtempMax<pointCloud[tempNode->data[j]].x)
                {
                    xtempMax = pointCloud[tempNode->data[j]].x;
                }
    
                if (ytempMin>pointCloud[tempNode->data[j]].y)
                {
                    ytempMin = pointCloud[tempNode->data[j]].y;
                }
                if (ytempMax<pointCloud[tempNode->data[j]].y)
                {
                    ytempMax = pointCloud[tempNode->data[j]].y;
                }
    
                if (ztempMin>pointCloud[tempNode->data[j]].z)
                {
                    ztempMin = pointCloud[tempNode->data[j]].z;
                }
                if (ztempMax<pointCloud[tempNode->data[j]].z)
                {
                    ztempMax = pointCloud[tempNode->data[j]].z;
                }
            }
    
            float xtemp = xtempMax - xtempMin;
            float ytemp = ytempMax - ytempMin;
            float ztemp = ztempMax - ztempMin;
            if (xtemp>ytemp && xtemp>ztemp)
            {
                slipnum = 1;
                tempNode->splitScale[0] = xtempMin;
                tempNode->splitScale[1] = xtempMax;
            }
            else if (ytemp>xtemp && ytemp>ztemp)
            {
                slipnum = 2;
                tempNode->splitScale[0] = ytempMin;
                tempNode->splitScale[1] = ytempMax;
            }
            else
            {
                slipnum = 3;
                tempNode->splitScale[0] = ztempMin;
                tempNode->splitScale[1] = ztempMax;
            }
    
            deltaNum = tempNode->splitScale[1] - tempNode->splitScale[0];
    
            //首先判断是否符合叶子节点
            if (tempNode->numOfData < numOfLeafData || deltaNum < scaleOfLeafNode)
            {
                tempNode->dim = -1;       //可用判断是否是叶子节点
    
                octreeNodePtrQue.pop();
                if (octreeNodePtrQue.size() == 0)
                {
                    break;
                }
                tempNode = octreeNodePtrQue.front();
                continue;
            }
    
    
            //构造8个节点子树        
            for (size_t i= 0; i < 8; i++)
            {
                ocTreeNode* tempOcTreenode = new ocTreeNode;
                tempNode->ocTreeNodePtrVect.push_back(tempOcTreenode);
            }
    
            std::vector<size_t> *dataIndexTemp = new std::vector<size_t>[8];
    
            //数据分割到8子节点上
            for (size_t i = 0; i < tempNode->numOfData; i++)
            {
                if (slipnum == 1)
                {
                    tempNode->dim = 1;
    
                    if (pointCloud[(tempNode->data)[i]].x < (tempNode->splitScale[0] + (deltaNum / 8)))
                    {
                        dataIndexTemp[0].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].x >= (tempNode->splitScale[0] + (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].x < (tempNode->splitScale[0] + 2 * (deltaNum / 8)))
                    {
                        dataIndexTemp[1].push_back((tempNode->data)[i]);
    
                    }
                    else if (pointCloud[(tempNode->data)[i]].x >= (tempNode->splitScale[0] + 2 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].x < (tempNode->splitScale[0] + 3 * (deltaNum / 8))) {
    
                        dataIndexTemp[2].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].x >= (tempNode->splitScale[0] + 3 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].x < (tempNode->splitScale[0] + 4 * (deltaNum / 8)))
                    {
                        dataIndexTemp[3].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].x >= (tempNode->splitScale[0] + 4 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].x < (tempNode->splitScale[0] + 5 * (deltaNum / 8)))
                    {
                        dataIndexTemp[4].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].x >= (tempNode->splitScale[0] + 5 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].x < (tempNode->splitScale[0] + 6 * (deltaNum / 8)))
                    {
                        dataIndexTemp[5].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].x >= (tempNode->splitScale[0] + 6 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].x < (tempNode->splitScale[0] + 7 * (deltaNum / 8)))
                    {
                        dataIndexTemp[6].push_back((tempNode->data)[i]);
                    }
                    else
                    {
                        dataIndexTemp[7].push_back((tempNode->data)[i]);
                    }
            
                }
                else if (slipnum == 2) {
    
                    tempNode->dim = 2;
    
                    if (pointCloud[(tempNode->data)[i]].y < (tempNode->splitScale[0] + (deltaNum / 8)))
                    {
                        dataIndexTemp[0].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].y >= (tempNode->splitScale[0] + (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].y < (tempNode->splitScale[0] + 2 * (deltaNum / 8)))
                    {
                        dataIndexTemp[1].push_back((tempNode->data)[i]);
    
                    }
                    else if (pointCloud[(tempNode->data)[i]].y >= (tempNode->splitScale[0] + 2 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].y < (tempNode->splitScale[0] + 3 * (deltaNum / 8))) {
    
                        dataIndexTemp[2].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].y >= (tempNode->splitScale[0] + 3 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].y < (tempNode->splitScale[0] + 4 * (deltaNum / 8)))
                    {
                        dataIndexTemp[3].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].y >= (tempNode->splitScale[0] + 4 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].y < (tempNode->splitScale[0] + 5 * (deltaNum / 8)))
                    {
                        dataIndexTemp[4].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].y >= (tempNode->splitScale[0] + 5 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].y < (tempNode->splitScale[0] + 6 * (deltaNum / 8)))
                    {
                        dataIndexTemp[5].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].y >= (tempNode->splitScale[0] + 6 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].y < (tempNode->splitScale[0] + 7 * (deltaNum / 8)))
                    {
                        dataIndexTemp[6].push_back((tempNode->data)[i]);
                    }
                    else
                    {
                        dataIndexTemp[7].push_back((tempNode->data)[i]);
                    }
                }
                else
                {
                    tempNode->dim = 3;
                    if (pointCloud[(tempNode->data)[i]].z < (tempNode->splitScale[0] + (deltaNum / 8)))
                    {
                        dataIndexTemp[0].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].z >= (tempNode->splitScale[0] + (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].z < (tempNode->splitScale[0] + 2 * (deltaNum / 8)))
                    {
                        dataIndexTemp[1].push_back((tempNode->data)[i]);
    
                    }
                    else if (pointCloud[(tempNode->data)[i]].z >= (tempNode->splitScale[0] + 2 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].z < (tempNode->splitScale[0] + 3 * (deltaNum / 8))) {
    
                        dataIndexTemp[2].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].z >= (tempNode->splitScale[0] + 3 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].z < (tempNode->splitScale[0] + 4 * (deltaNum / 8)))
                    {
                        dataIndexTemp[3].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].z >= (tempNode->splitScale[0] + 4 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].z < (tempNode->splitScale[0] + 5 * (deltaNum / 8)))
                    {
                        dataIndexTemp[4].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].z >= (tempNode->splitScale[0] + 5 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].z < (tempNode->splitScale[0] + 6 * (deltaNum / 8)))
                    {
                        dataIndexTemp[5].push_back((tempNode->data)[i]);
                    }
                    else if (pointCloud[(tempNode->data)[i]].z >= (tempNode->splitScale[0] + 6 * (deltaNum / 8))
                        && pointCloud[(tempNode->data)[i]].z < (tempNode->splitScale[0] + 7 * (deltaNum / 8)))
                    {
                        dataIndexTemp[6].push_back((tempNode->data)[i]);
                    }
                    else
                    {
                        dataIndexTemp[7].push_back((tempNode->data)[i]);
                    }
                }
            }
    
    
            //更新子树
            for (size_t i = 0; i < 8; i++)
            {
                tempNode->ocTreeNodePtrVect[i]->data = new size_t[dataIndexTemp[i].size()];
                for (size_t t = 0; t < dataIndexTemp[i].size(); t++)
                {
                    tempNode->ocTreeNodePtrVect[i]->data[t] = dataIndexTemp[i][t];
                }
    
                tempNode->ocTreeNodePtrVect[i]->numOfData = dataIndexTemp[i].size();
                tempNode->ocTreeNodePtrVect[i]->nodePos = i;
                tempNode->ocTreeNodePtrVect[i]->father = tempNode;
    
                octreeNodePtrQue.push(tempNode->ocTreeNodePtrVect[i]);
            }
    
            octreeNodePtrQue.pop();
            if (octreeNodePtrQue.size() == 0)
            {
                break;
            }
            tempNode = octreeNodePtrQue.front();   //更新节点
        }
    
        return 0;
    }
  • 相关阅读:
    JAVA this
    JAVA static关键字
    子类实例化 super
    TCP/IP概述
    Java多态
    植物大战僵尸:寻找阳光掉落Call调用
    JVM总结+个人整理补充--转
    已知微分方程通解求微分方程
    Redis安装过程中的问题
    对称阵和反对称阵
  • 原文地址:https://www.cnblogs.com/lovebay/p/11757186.html
Copyright © 2011-2022 走看看