#include<iostream>#include<vector>#defineMAX_DEEP5#defineBOX_SIDE100namespace KS
{structPoint{double x;double y;double z;Point(double x_,double y_,double z_):x(x_),y(y_),z(z_){}booloperator==(Point& point){return point.x == x && point.y == y && point.z == z;}};structNode{double x, y, z;double sideLength;
std::vector<Point> points;// all actors inside current space. structNode* childs[8];Node(double x_,double y_,double z_,double sideLength_):x(x_),y(y_),z(z_),sideLength(sideLength_){}};classOctree{private:structNode* head =nullptr;
Node*init(int x,int y,int z,int side,int deep){if(deep > MAX_DEEP){returnnullptr;}
Node* root =newNode(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;}voiduninit(Node* root,int deep){if(deep > MAX_DEEP){return;}for(int i =0; i <8;++i){uninit(root->childs[i], deep+1);}delete root;}voiddeepFind(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);}}booldeepInsert(Node* root, Point target,int deep){if(root ==nullptr){returnfalse;}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){returnfalse;// don’t in this space.}if(deep == MAX_DEEP){
root->points.push_back(target);returntrue;// 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;}boolfind(Point target){
Node* value =nullptr;deepFind(this->head, target,1, value);if(value ==nullptr){returnfalse;}else{returntrue;}}boolinsert(Point target){returndeepInsert(this->head, target,1);}~Octree(){this->uninit(this->head,1);}};}