C++实现八叉树

C++实现八叉树

#include <iostream>
#include <vector>
#define MAX_DEEP 5
#define BOX_SIDE 100

namespace KS
{
    struct Point
    {
        double x;
        double y;
        double z;
        Point(double x_, double y_, double z_):x(x_), y(y_), z(z_) {}
        bool operator==(Point& point)
        {
            return point.x == x && point.y == y && point.z == z;
        }
    };

    struct Node
    {
        double x, y, z;
        double sideLength;
        std::vector<Point> points;   // all actors inside current space. 
        struct Node* childs[8];
        Node(double x_, double y_, double z_, double sideLength_):x(x_),y(y_),z(z_),sideLength(sideLength_) {}
    };

    class Octree
    {
    private:
        struct Node* head = nullptr;
        Node* init(int x, int y, int z, int side, int deep)
        {
            if (deep > MAX_DEEP)
            {
                return nullptr;
            }
            Node* root = new Node(x, y, z, side);
            root->childs[0] = init(x - side / 4, y - side / 4, z + side / 4, side / 2, deep + 1);
            root->childs[1] = init(x - side / 4, y + side / 4, z + side / 4, side / 2, deep + 1);
            root->childs[2] = init(x + side / 4, y - side / 4, z + side / 4, side / 2, deep + 1);
            root->childs[3] = init(x + side / 4, y + side / 4, z + side / 4, side / 2, deep + 1);
            root->childs[4] = init(x - side / 4, y + side / 4, z - side / 4, side / 2, deep + 1);
            root->childs[5] = init(x - side / 4, y - side / 4, z - side / 4, side / 2, deep + 1);
            root->childs[6] = init(x + side / 4, y + side / 4, z - side / 4, side / 2, deep + 1);
            root->childs[7] = init(x + side / 4, y - side / 4, z - side / 4, side / 2, deep + 1);
            return root;
        }

        void uninit(Node* root, int deep)
        {
            if (deep > MAX_DEEP)
            {
                return;
            }
            for (int i = 0; i < 8; ++i)
            {
                uninit(root->childs[i], deep+1);
            }
            delete root;
        }

        void deepFind(Node* root, Point target, int deep, Node*& value)
        {
            if (root == nullptr)
            {
                return;
            }

            double side = root->sideLength;
            double rootX = root->x;
            double rootY = root->y;
            double rootZ = root->z;
            if (((rootX - side / 2 <= target.x && rootX + side / 2 >= target.x) || 
                 (rootY - side / 2 <= target.y && rootY + side / 2 >= target.y) || 
                 (rootZ - side / 2 <= target.z && rootZ + side / 2 >= target.z)) == false)
            {
                return; // don’t in this space.
            }

            if (deep == MAX_DEEP)
            {
                for (auto &&point : root->points)
                {
                    if (point == target)
                    {
                        value = root;
                        return;
                    }
                }
                return;    // in this space.
            }

            for (int i = 0; i < 8; ++i)
            {
                deepFind(root->childs[i], target, deep + 1, value); 
            }
        }

        bool deepInsert(Node* root, Point target, int deep)
        {
            if (root == nullptr)
            {
                return false;
            }
            double side = root->sideLength;
            double rootX = root->x;
            double rootY = root->y;
            double rootZ = root->z;
            if (((rootX - side / 2 <= target.x&& rootX + side / 2 >= target.x) && 
                 (rootY - side / 2 <= target.y&& rootY + side / 2 >= target.y) && 
                 (rootZ - side / 2 <= target.z&& rootZ + side / 2 >= target.z)) == false)
            {
                return false; // don’t in this space.
            }

            if (deep == MAX_DEEP)
            {
                root->points.push_back(target);
                return true;    // in this space.
            }

            bool value = false;
            for (int i = 0; i < 8; ++i)
            {
                value = value || deepInsert(root->childs[i], target, deep + 1);
            }
            return value;
        }

    public:
        Octree()
        {
            this->head = init(0, 0, 0, BOX_SIDE, 1);
            return;
        }

        bool find(Point target)
        {
            Node* value = nullptr;
            deepFind(this->head, target, 1, value);
            if (value == nullptr)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        
        bool insert(Point target)
        {
            return deepInsert(this->head, target, 1);
        }

        ~Octree()
        {
            this->uninit(this->head, 1);
        }
    };
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙子砰砰枪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值