QuadTree 优化版

 

QuadTree.h

#pragma once
#include <iostream>
#include <string>
#include <stdlib.h>
#include <ctime>
#include <vector>
#include <algorithm>
using namespace std;

#define MAX_ELE_NUM 300   //每块区域的最大点数
#define QUADRANT_RU 1
#define QUADRANT_LU 2
#define QUADRANT_LB 3
#define QUADRANT_RB 4

//extern int maxDepth;

//矩形区域
struct Region
{
    double bottom;
    double up;
    double left;
    double right;
};
   
//点结构体
struct ElePoint
{
    int idx{ -1 };
    float x;   //x坐标
    float y;   //y坐标
    float z{ 0 };   //y坐标
};

//四叉树结点
struct QuadTreeNode
{
    int depth;   //结点的深度
    int is_leaf;   //是否是叶子节点
    struct Region region;   //区域范围
    struct QuadTreeNode *LU;  //左上子节点指针
    struct QuadTreeNode *LB;   //左下子节点指针
    struct QuadTreeNode *RU;   //右上子节点指针
    struct QuadTreeNode *RB;   //右下子节点指针
    int ele_num;     //矩形区域中位置点数
    struct ElePoint *ele_list[MAX_ELE_NUM];   //矩形区域中位置点列表
};

struct neiInfo
{
    ElePoint pt;
    float dis{ -1 };
};

struct  prioBranchQueueEntry
{
    QuadTreeNode node;
    float dis{ 9999999 };
};

struct  prioPointQueueEntry
{
    ElePoint pt;
    float dis{ -1 };
};


class  QuadTree
{
public:
    QuadTree()
    {
    
    }

    ~QuadTree()
    {

    }

public:
    void setInputPoints(std::vector<ElePoint>&points1);
    bool initialTree();
    float knnSearch(ElePoint ele, int k, vector<int>&idxVec, vector<float>&disVec);
    float radiusSearch(ElePoint ele, float radius, vector<int>&idxVec, vector<float>&disVec);

private:
    bool getRegion();
    bool isBuildTreeSuccess{false};

public:
    std::vector<ElePoint> points;
    QuadTreeNode root;
    Region root_region;
    int treeMaxDepth{0};

    float minX{ (float)DBL_MAX };
    float maxX{ -(float)DBL_MAX };
    float minY{ (float)DBL_MAX };
    float maxY{ -(float)DBL_MAX };
};

 

QuadTree.cpp

#include "stdafx.h"
#include "QuadTree.h"
#include <cmath>

int maxDepth = 0;
float knnMinDis = 9999999;
std::vector<prioPointQueueEntry> searchResult;
//std::vector<neiInfo>ElePointSearchVec;

//函数声明
void initNode(QuadTreeNode *node, int depth, Region region);
void insertEle(QuadTreeNode *node, ElePoint ele);
void splitNode(QuadTreeNode *node);
void queryEle(QuadTreeNode tree, ElePoint ele);
void initRegion(Region *region, double up, double bottom, double left, double right);
QuadTreeNode *createChildNode(QuadTreeNode *node, double bottom, double up, double left, double right);

bool ptIsInRegion(ElePoint pt, double bottom, double up, double left, double right)
{
    if (pt.x > left && pt.x<right && pt.y>bottom && pt.y < up)
    {
        return true;
    }
    return false;
}

float twoPtDis(ElePoint p1, ElePoint p2)
{
    return abs(sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2)));
}

/**
* 插入元素
* 1.判断是否已分裂,已分裂的选择适合的子结点,插入;
* 2.未分裂的查看是否过载,过载的分裂结点,重新插入;
* 3.未过载的直接添加
*
* @param node
* @param ele
* todo 使用元素原地址,避免重新分配内存造成的效率浪费
*/
void insertEle(QuadTreeNode *node, ElePoint ele)
{
    //是叶子结点
    if (1 == node->is_leaf)
    {
        if (node->ele_num + 1 > MAX_ELE_NUM)//大于100个点就要分裂成2个节点
        {
            splitNode(node);

            //分裂后的 node 不是叶子节点,所以新插入的元素会插入到 node 的子节点上
            insertEle(node, ele);  //将新插入的元素插入到node的子节点上
        }
        else
        {
            ElePoint *ele_ptr = (ElePoint *)malloc(sizeof(ElePoint));
            ele_ptr->y = ele.y;
            ele_ptr->x = ele.x;
            ele_ptr->idx = ele.idx;
            //将新插入的点加入到父节点的位置点列表中
            node->ele_list[node->ele_num] = ele_ptr;
            node->ele_num++;
        }

        return;
    }

    //不是叶子结点
    double mid_vertical = (node->region.up + node->region.bottom) / 2;
    double mid_horizontal = (node->region.left + node->region.right) / 2;
    if (ele.y > mid_vertical)
    {
        if (ele.x > mid_horizontal)
        {
            insertEle(node->RU, ele);
        }
        else
        {
            insertEle(node->LU, ele);
        }
    }
    else
    {
        if (ele.x > mid_horizontal)
        {
            insertEle(node->RB, ele);
        }
        else
        {
            insertEle(node->LB, ele);
        }
    }
}

//创建子节点
QuadTreeNode *createChildNode(struct QuadTreeNode *node, double bottom, double up, double left, double right)
{
    int depth = node->depth + 1;
    QuadTreeNode *childNode = (QuadTreeNode *)malloc(sizeof(QuadTreeNode));
    Region *region = (Region *)malloc(sizeof(Region));
    initRegion(region, bottom, up, left, right);
    initNode(childNode, depth, *region);

    maxDepth = std::max(maxDepth, depth);
    return childNode;
}

//初始化四叉树结点
void initNode(QuadTreeNode *node, int depth, Region region)
{
    node->depth = depth;
    node->is_leaf = 1;
    node->ele_num = 0;
    node->region = region;
}

//初始化矩形区域
void initRegion(Region *region, double yMin, double yMax, double xMin, double xMax)
{
    region->bottom = yMin;
    region->up = yMax;
    region->left = xMin;
    region->right = xMax;
}

/**
* 分裂结点
* 1.通过父结点获取子结点的深度和范围
* 2.生成四个结点,挂载到父结点下
*
* @param node
*/
void splitNode(struct QuadTreeNode *node)
{
    double mid_vertical = (node->region.up + node->region.bottom) / 2;  //垂直放向的中间线
    double mid_horizontal = (node->region.left + node->region.right) / 2; //水平方向的中间线

    node->is_leaf = 0;

    //生成四个孩子结点
    node->RU = createChildNode(node, mid_vertical, node->region.up, mid_horizontal, node->region.right);
    node->LU = createChildNode(node, mid_vertical, node->region.up, node->region.left, mid_horizontal);
    node->RB = createChildNode(node, node->region.bottom, mid_vertical, mid_horizontal, node->region.right);
    node->LB = createChildNode(node, node->region.bottom, mid_vertical, node->region.left, mid_horizontal);

    for (int i = 0; i < node->ele_num; i++)
    {
        //此时插入的时候,node不是叶子节点,此时执行 insert 函数,会将元素插入到孩子节点上
        insertEle(node, *node->ele_list[i]);   // 将父节点元素 插入到子节点
        free(node->ele_list[i]);   //释放父节点元素

                                   //node->ele_num--;//这里每次循环的时候i在增加,而node.ele_num在减少,会导致有的点没有插进去
                                   //所以直接在循环结束后,将node.ele_num置为0即可
    }
    node->ele_num = 0;
}

//区域查询  输出该点所在的矩形区域的所有点
void queryEle(struct QuadTreeNode node, struct ElePoint ele)
{
    //是叶子结点
    if (node.is_leaf == 1 /*&& ptIsInRegion(ele, node.region.bottom, node.region.up, node.region.left, node.region.right)*/)
    {
        cout << "miny" << node.region.bottom << endl;
        cout << "maxy" << node.region.up << endl;
        cout << "minx" << node.region.left << endl;
        cout << "maxx" << node.region.right << endl;

        cout << "附近点有" << node.ele_num << "个,分别是:" << endl;
        for (int j = 0; j < node.ele_num; j++)
        {
            cout << "(" << node.ele_list[j]->x << "," << node.ele_list[j]->y << ")" << endl;
        }
        return;
    }

    //不是叶子节点
    double mid_vertical = (node.region.up + node.region.bottom) / 2;
    double mid_horizontal = (node.region.left + node.region.right) / 2;

    if (ele.y > mid_vertical)
    {
        if (ele.x > mid_horizontal)
        {
            queryEle(*node.RU, ele);
        }
        else
        {
            queryEle(*node.LU, ele);
        }
    }
    else
    {
        if (ele.x > mid_horizontal)
        {
            queryEle(*node.RB, ele);
        }
        else
        {
            queryEle(*node.LB, ele);
        }
    }
}

//点查询
void queryPoint(QuadTreeNode node, ElePoint &ele)
{
    //是叶子节点
    if (node.is_leaf == 1)
    {
        for (int i = 0; i < node.ele_num; i++)
        {
            if (ele.x == node.ele_list[i]->x&&ele.y == node.ele_list[i]->y)
            {
                cout << "(" << node.ele_list[i]->x << "," << node.ele_list[i]->y << ") 位于第" << node.depth << "" << endl;
                return;
            }
        }
        cout << "未找到该点!" << endl;
        return;
    }

    //不是叶子结点
    double mid_vertical = (node.region.up + node.region.bottom) / 2;
    double mid_horizontal = (node.region.left + node.region.right) / 2;


    if (ele.x > mid_horizontal)
    {
        if (ele.y > mid_vertical)
        {
            //queryPoint(QTList[node.RU_0], ele);
            queryPoint(*node.RU, ele);
        }
        else
        {
            //queryPoint(QTList[node.RB_3], ele);
            queryPoint(*node.RB, ele);
        }
    }
    else
    {
        if (ele.y > mid_vertical)
        {
            //queryPoint(QTList[node.LU_1], ele);
            queryPoint(*node.LU, ele);
        }
        else
        {
            //queryPoint(QTList[node.LB_2], ele);
            queryPoint(*node.LB, ele);
        }
    }
}

//任意区域查询
void queryArea(QuadTreeNode *node, Region *region)
{    //是叶子节点
    if (node->is_leaf == 1)
    {
        //遍历叶子节点中的所有点
        for (int i = 0; i < node->ele_num; i++)
        {
            //如果叶子节点中有点在该矩形区域中,就输出该点坐标
            if (node->ele_list[i]->x >= region->left &&
                node->ele_list[i]->x <= region->right &&
                node->ele_list[i]->y >= region->bottom &&
                node->ele_list[i]->y <= region->up)
            {
                cout << "(" << node->ele_list[i]->x << "," << node->ele_list[i]->y << ") ";
            }
        }
        cout << endl;
        return;
    }

    //不是叶子结点 , 递归查找与矩形区域有交集的叶子结点
    double mid_vertical = (node->region.up + node->region.bottom) / 2;
    double mid_horizontal = (node->region.left + node->region.right) / 2;

    //讨论矩形区域的9种分布情况
    if (region->bottom > mid_vertical) {
        if (region->left > mid_horizontal) {
            //如果矩形区域的下边界大,左边界大,就在右上区域查询
            queryArea(node->RU, region);
        }
        else if (region->right < mid_horizontal) {
            queryArea(node->LU, region);
        }
        else {
            //将该矩形区域分成两块,逐块递归判断其所属的子区域
            Region *region1 = (Region *)malloc(sizeof(Region));
            *region1 = { region->bottom,region->up,region->left,mid_horizontal };
            queryArea(node->LU, region1);

            Region *region2 = (Region *)malloc(sizeof(Region));
            *region2 = { region->bottom,region->up,mid_horizontal,region->right };
            queryArea(node->RU, region2);
        }
    }

    else if (region->up < mid_vertical) {
        if (region->right < mid_horizontal) {
            queryArea(node->LB, region);
        }
        else if (region->left > mid_horizontal) {
            queryArea(node->RB, region);
        }
        else {
            Region *region1 = (Region *)malloc(sizeof(Region));
            *region1 = { region->bottom, region->up,region->left,mid_horizontal };
            queryArea(node->LB, region1);

            Region *region2 = (Region *)malloc(sizeof(Region));
            *region2 = { region->bottom,region->up,mid_horizontal,region->right };
            queryArea(node->RB, region2);
        }
    }

    else {
        if (region->right < mid_horizontal) {
            Region *region1 = (Region *)malloc(sizeof(Region));
            *region1 = { mid_vertical,region->up,region->left,region->right };
            queryArea(node->LU, region1);

            Region *region2 = (Region *)malloc(sizeof(Region));
            *region2 = { region->bottom,mid_vertical,region->left,region->right };
            queryArea(node->LB, region2);

        }
        else if (region->left > mid_horizontal) {
            Region *region1 = (Region *)malloc(sizeof(Region));
            *region1 = { mid_vertical,region->up,region->left,region->right };
            queryArea(node->RU, region1);

            Region *region2 = (Region *)malloc(sizeof(Region));
            *region2 = { region->bottom,mid_vertical,region->left,region->right };
            queryArea(node->RB, region2);
        }
        else {
            Region *region1 = (Region *)malloc(sizeof(Region));
            *region1 = { mid_vertical,region->up,region->left,mid_horizontal };
            queryArea(node->LU, region1);

            Region *region2 = (Region *)malloc(sizeof(Region));
            *region2 = { mid_vertical,region->up,mid_horizontal,region->right };
            queryArea(node->RU, region2);

            Region *region3 = (Region *)malloc(sizeof(Region));
            *region3 = { region->bottom,mid_vertical,region->left,mid_horizontal };
            queryArea(node->LB, region3);

            Region *region4 = (Region *)malloc(sizeof(Region));
            *region4 = { region->bottom, mid_vertical,mid_horizontal,region->right };
            queryArea(node->RB, region4);
        }
    }
}

float knnSearchEx(QuadTreeNode node, ElePoint ele, int k)
{
    std::vector<prioBranchQueueEntry> search_heap;

    float curNodeXlen = node.region.right - node.region.left;
    float curNodeYlen = node.region.up - node.region.bottom;

    //先将节点分成4个节点
    if (node.is_leaf != 1)
    {
        ElePoint curCentPt;
        prioBranchQueueEntry prioBranchQueueEntryT;

        node.RU;
        curCentPt.x = (node.RU->region.left + node.RU->region.right) / 2;
        curCentPt.y = (node.RU->region.bottom + node.RU->region.up) / 2;
        prioBranchQueueEntryT.node = *node.RU;
        prioBranchQueueEntryT.dis = twoPtDis(ele, curCentPt);
        search_heap.push_back(prioBranchQueueEntryT);

        node.LU;
        curCentPt.x = (node.LU->region.left + node.LU->region.right) / 2;
        curCentPt.y = (node.LU->region.bottom + node.LU->region.up) / 2;
        prioBranchQueueEntryT.node = *node.LU;
        prioBranchQueueEntryT.dis = twoPtDis(ele, curCentPt);
        search_heap.push_back(prioBranchQueueEntryT);

        node.RB;
        curCentPt.x = (node.RB->region.left + node.RB->region.right) / 2;
        curCentPt.y = (node.RB->region.bottom + node.RB->region.up) / 2;
        prioBranchQueueEntryT.node = *node.RB;
        prioBranchQueueEntryT.dis = twoPtDis(ele, curCentPt);
        search_heap.push_back(prioBranchQueueEntryT);

        node.LB;
        curCentPt.x = (node.LB->region.left + node.LB->region.right) / 2;
        curCentPt.y = (node.LB->region.bottom + node.LB->region.up) / 2;
        prioBranchQueueEntryT.node = *node.LB;
        prioBranchQueueEntryT.dis = twoPtDis(ele, curCentPt);
        search_heap.push_back(prioBranchQueueEntryT);
    }

    std::sort(search_heap.begin(), search_heap.end(), [](prioBranchQueueEntry& p1, prioBranchQueueEntry& p2) {return p1.dis > p2.dis; });

    int aa = 1;

    while (
        !search_heap.empty()
        /*&&(search_heap.back().dis < (knnMinDis+max(curNodeXlen,curNodeYlen) ) )*/
        )
    {
        curNodeXlen = search_heap.back().node.region.right - search_heap.back().node.region.left;
        curNodeYlen = search_heap.back().node.region.up - search_heap.back().node.region.bottom;

        float dis1 = search_heap.back().dis;
        float disT = sqrt(pow(curNodeXlen / 2, 2) + pow(curNodeYlen / 2, 2));
        float dis2 = knnMinDis + disT/* max(curNodeXlen, curNodeYlen)*/;

        if (dis1 < dis2)
        {
            if (search_heap.back().node.is_leaf != 1)
            {
                knnMinDis = knnSearchEx(search_heap.back().node, ele, k);
            }
            else
            {
                QuadTreeNode& nodeT = search_heap.back().node;
                for (int i = 0; i < nodeT.ele_num; i++)
                {
                    float dis = twoPtDis(*nodeT.ele_list[i], ele);
                    if (dis < knnMinDis)
                    {
                        prioPointQueueEntry point_entry;
                        point_entry.pt = *nodeT.ele_list[i];
                        point_entry.dis = dis;
                        searchResult.push_back(point_entry);
                    }
                }

                std::sort(searchResult.begin(), searchResult.end(), [](prioPointQueueEntry& p1, prioPointQueueEntry& p2) {return p1.dis < p2.dis; });
                if (searchResult.size() > k)
                    searchResult.resize(k);
                knnMinDis = searchResult.back().dis;
            }
        }

        search_heap.pop_back();
    }

    return knnMinDis;
}

float radiusSearchEx(QuadTreeNode node, ElePoint ele, float radius)
{
    std::vector<prioBranchQueueEntry> search_heap;

    float curNodeXlen = node.region.right - node.region.left;
    float curNodeYlen = node.region.up - node.region.bottom;

    //先将节点分成4个节点
    if (node.is_leaf != 1)
    {
        ElePoint curCentPt;
        prioBranchQueueEntry prioBranchQueueEntryT;

        node.RU;
        curCentPt.x = (node.RU->region.left + node.RU->region.right) / 2;
        curCentPt.y = (node.RU->region.bottom + node.RU->region.up) / 2;
        prioBranchQueueEntryT.node = *node.RU;
        prioBranchQueueEntryT.dis = twoPtDis(ele, curCentPt);
        search_heap.push_back(prioBranchQueueEntryT);

        node.LU;
        curCentPt.x = (node.LU->region.left + node.LU->region.right) / 2;
        curCentPt.y = (node.LU->region.bottom + node.LU->region.up) / 2;
        prioBranchQueueEntryT.node = *node.LU;
        prioBranchQueueEntryT.dis = twoPtDis(ele, curCentPt);
        search_heap.push_back(prioBranchQueueEntryT);

        node.RB;
        curCentPt.x = (node.RB->region.left + node.RB->region.right) / 2;
        curCentPt.y = (node.RB->region.bottom + node.RB->region.up) / 2;
        prioBranchQueueEntryT.node = *node.RB;
        prioBranchQueueEntryT.dis = twoPtDis(ele, curCentPt);
        search_heap.push_back(prioBranchQueueEntryT);

        node.LB;
        curCentPt.x = (node.LB->region.left + node.LB->region.right) / 2;
        curCentPt.y = (node.LB->region.bottom + node.LB->region.up) / 2;
        prioBranchQueueEntryT.node = *node.LB;
        prioBranchQueueEntryT.dis = twoPtDis(ele, curCentPt);
        search_heap.push_back(prioBranchQueueEntryT);
    }

    std::sort(search_heap.begin(), search_heap.end(), [](prioBranchQueueEntry& p1, prioBranchQueueEntry& p2) {return p1.dis < p2.dis; });

#define useFunc1 1
#ifdef useFunc1
    for (size_t i = 0; i < search_heap.size(); i++)
    {
        curNodeXlen = search_heap[i].node.region.right - search_heap[i].node.region.left;
        curNodeYlen = search_heap[i].node.region.up - search_heap[i].node.region.bottom;

        float dis1 = search_heap[i].dis;
        float disT = sqrt(pow(curNodeXlen / 2, 2) + pow(curNodeYlen / 2, 2));
        float dis2 = radius + disT/* max(curNodeXlen, curNodeYlen)*/;

        if (dis1 < dis2)
        {
            if (search_heap[i].node.is_leaf != 1)
            {
                radiusSearchEx(search_heap[i].node, ele, radius);
            }
            else
            {
                QuadTreeNode& nodeT = search_heap[i].node;
                for (int i = 0; i < nodeT.ele_num; i++)
                {
                    float dis = twoPtDis(*nodeT.ele_list[i], ele);
                    if (dis <= radius)
                    {
                        prioPointQueueEntry point_entry;
                        point_entry.pt = *nodeT.ele_list[i];
                        point_entry.dis = dis;
                        searchResult.push_back(point_entry);
                    }
                }
            }
        }
    }
    std::sort(searchResult.begin(), searchResult.end(), [](prioPointQueueEntry& p1, prioPointQueueEntry& p2) {return p1.dis < p2.dis; });
    //方法二
#else
    while (!search_heap.empty())
    {
        curNodeXlen = search_heap.back().node.region.right - search_heap.back().node.region.left;
        curNodeYlen = search_heap.back().node.region.up - search_heap.back().node.region.bottom;

        float dis1 = search_heap.back().dis;
        float disT = sqrt(pow(curNodeXlen / 2, 2) + pow(curNodeYlen / 2, 2));
        float dis2 = radius + disT/* max(curNodeXlen, curNodeYlen)*/;

        if (dis1 < dis2)
        {
            if (search_heap.back().node.is_leaf != 1)
            {
                radiusSearch(search_heap.back().node, ele, radius);
            }
            else
            {
                QuadTreeNode& nodeT = search_heap.back().node;
                for (int i = 0; i < nodeT.ele_num; i++)
                {
                    float dis = twoPtDis(*nodeT.ele_list[i], ele);
                    if (dis <= radius)
                    {
                        prioPointQueueEntry point_entry;
                        point_entry.pt = *nodeT.ele_list[i];
                        point_entry.dis = dis;
                        searchResult.push_back(point_entry);
                    }
                }

                std::sort(searchResult.begin(), searchResult.end(), [](prioPointQueueEntry& p1, prioPointQueueEntry& p2) {return p1.dis < p2.dis; });
            }
        }

        search_heap.pop_back();
    }
#endif

    return knnMinDis;
}

void QuadTree::setInputPoints(std::vector<ElePoint>&points1)
{
    points = points1;
}

bool QuadTree::getRegion()
{
    for (int i=0;i<points.size();i++)
    {
        minX = std::min(points[i].x, minX);
        maxX = std::max(points[i].x, maxX);

        minY = std::min(points[i].y, minY);
        maxY = std::max(points[i].y, maxY);
    }

    return isfinite(minX)&& isfinite(maxX)&& isfinite(minY)&& isfinite(maxY);
}

bool QuadTree::initialTree()
{
    if (getRegion())
    {
        initRegion(&root_region, minY,maxY, minX, maxX);
        initNode(&root, 1, root_region);

        for (int i=0;i<points.size();i++)
        {
            insertEle(&root, points[i]);
        }

        treeMaxDepth = maxDepth;
        isBuildTreeSuccess = true;
        return true;
    }
    else
    {
        isBuildTreeSuccess = false;
        return false;
    }
}

float QuadTree::knnSearch(ElePoint ele, int k, vector<int>&idxVec, vector<float>&disVec)
{
    if (!isBuildTreeSuccess)
    {
        return -1;
    }

    knnMinDis=knnSearchEx(root,ele,k);

    for (int i = 0; i < searchResult.size(); i++)
    {
        idxVec.push_back(searchResult[i].pt.idx);
        disVec.push_back(searchResult[i].dis);
    }

    return knnMinDis;
}

float QuadTree::radiusSearch(ElePoint ele, float radius, vector<int>&idxVec, vector<float>&disVec)
{
    if (!isBuildTreeSuccess)
    {
        return -1;
    }

    knnMinDis = radiusSearchEx(root, ele, radius);

    for (int i = 0; i < searchResult.size(); i++)
    {
        idxVec.push_back(searchResult[i].pt.idx);
        disVec.push_back(searchResult[i].dis);
    }

    return knnMinDis;
}

 

main

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include "QuadTree.h"
using namespace std;

int main()
{
    std::vector<ElePoint>points1;
    
    ifstream inFile("Building_Test_12_p3_2_测试四叉树.txt",ios::in);
    int num = 0;
    while (!inFile.eof())
    {
        ElePoint pt;
        float x, y, z;
        inFile >> x >> y >> z;
        pt.x = x;
        pt.y = y;
        pt.z = z;
        pt.idx = num;
        num++;
        points1.push_back(pt);
    }

    QuadTree QuadTreeT;
    QuadTreeT.setInputPoints(points1);
    QuadTreeT.initialTree();

    ElePoint ele;
    ele.x = -70.15;
    ele.y = -30.15;
    vector<int>idxVec;
    vector<float>disVec;
    //QuadTreeT.knnSearch(ele, 80, idxVec, disVec);
    QuadTreeT.radiusSearch(ele,1, idxVec, disVec);
    ofstream outFile("knnNearst_r1.txt", ios::out);
    for (int i=0;i<idxVec.size();i++)
    {
        int curIdx = idxVec[i];
        outFile << points1[curIdx].x << " " << points1[curIdx].y << " " << points1[curIdx].z << endl;
    }
    outFile.close();
}

 

posted @ 2023-12-06 19:42  点小二  阅读(13)  评论(0编辑  收藏  举报