Octree | Insertion and Searching - GeeksforGeeks

25 Mar, 2022
Octree is a tree data structure in which each internal node can have at most 8 children. Like Binary tree which divides the space two segments, Octree divides the space into at most eight-part which is called as octanes. It is used to store the 3-D point which takes a large amount of space. if all the internal node of the Octree contains exactly 8 children is called full Octree. It is also useful for high-resolution graphics like 3D computer graphics.
The Octree can be formed form 3D volume by doing the following steps:  
Divide the current 3D volume into eight boxesIf any box has more than one point then divide it further into boxesDo not divide the box which has one or zero points in itDo this process repeatedly util all the box contains one or zero point in it
Divide the current 3D volume into eight boxes
If any box has more than one point then divide it further into boxes
Do not divide the box which has one or zero points in it
Do this process repeatedly util all the box contains one or zero point in it
The above steps are shown in figure.  
If S is the number of points in each dimension then the number of nodes that are formed in Octree is given by this formula .  
 
To insert a node in Octree, first of all, we check if a node exists or not if a node exists then return otherwise we go recursively
First, we start with the root node and mark it as current
Then we find the child node in which we can store the point
If the node is empty the replace with the node we want to insert and make it a leaf node
If the node is the leaf node then make it an internal node and if it is an internal node then go to the child node. do this process recursively till an empty node is not found
The time complexity of this function is where N is the number of nodes
 
 
This function is used to search the point exist is the tree or not
Start with the root node and search recursively if the node with given point found then return true if an empty node or boundary point or empty point is encountered then return false
If an internal node is found go that node. The time complexity of this function is also O(Log N) where N is the number of nodes
Below is the implementation of the above approach 
CPP14
// Implementation of Octree in c++#include <iostream>#include <vector>using namespace std; #define TopLeftFront 0#define TopRightFront 1#define BottomRightFront 2#define BottomLeftFront 3#define TopLeftBottom 4#define TopRightBottom 5#define BottomRightBack 6#define BottomLeftBack 7 // Structure of a pointstruct Point {    int x;    int y;    int z;    Point()        : x(-1), y(-1), z(-1)    {    }     Point(int a, int b, int c)        : x(a), y(b), z(c)    {    }}; // Octree classclass Octree {     // if point == NULL, node is internal node.    // if point == (-1, -1, -1), node is empty.    Point* point;     // Represent the boundary of the cube    Point *topLeftFront, *bottomRightBack;    vector<Octree*> children; public:    // Constructor    Octree()    {        // To declare empty node        point = new Point();    }     // Constructor with three arguments    Octree(int x, int y, int z)    {        // To declare point node        point = new Point(x, y, z);    }     // Constructor with six arguments    Octree(int x1, int y1, int z1, int x2, int y2, int z2)    {        // This use to construct Octree        // with boundaries defined        if (x2 < x1            || y2 < y1            || z2 < z1) {            cout << "boundary points are not valid" << endl;            return;        }         point = nullptr;        topLeftFront            = new Point(x1, y1, z1);        bottomRightBack            = new Point(x2, y2, z2);         // Assigning null to the children        children.assign(8, nullptr);        for (int i = TopLeftFront;             i <= BottomLeftBack;             ++i)            children[i] = new Octree();    }     // Function to insert a point in the octree    void insert(int x,                int y,                int z)    {         // If the point already exists in the octree        if (find(x, y, z)) {            cout << "Point already exist in the tree" << endl;            return;        }         // If the point is out of bounds        if (x < topLeftFront->x            || x > bottomRightBack->x            || y < topLeftFront->y            || y > bottomRightBack->y            || z < topLeftFront->z            || z > bottomRightBack->z) {            cout << "Point is out of bound" << endl;            return;        }         // Binary search to insert the point        int midx = (topLeftFront->x                    + bottomRightBack->x)                   / 2;        int midy = (topLeftFront->y                    + bottomRightBack->y)                   / 2;        int midz = (topLeftFront->z                    + bottomRightBack->z)                   / 2;         int pos = -1;         // Checking the octant of        // the point        if (x <= midx) {            if (y <= midy) {                if (z <= midz)                    pos = TopLeftFront;                else                    pos = TopLeftBottom;            }            else {                if (z <= midz)                    pos = BottomLeftFront;                else                    pos = BottomLeftBack;            }        }        else {            if (y <= midy) {                if (z <= midz)                    pos = TopRightFront;                else                    pos = TopRightBottom;            }            else {                if (z <= midz)                    pos = BottomRightFront;                else                    pos = BottomRightBack;            }        }         // If an internal node is encountered        if (children[pos]->point == nullptr) {            children[pos]->insert(x, y, z);            return;        }         // If an empty node is encountered        else if (children[pos]->point->x == -1) {            delete children[pos];            children[pos] = new Octree(x, y, z);            return;        }        else {            int x_ = children[pos]->point->x,                y_ = children[pos]->point->y,                z_ = children[pos]->point->z;            delete children[pos];            children[pos] = nullptr;            if (pos == TopLeftFront) {                children[pos] = new Octree(topLeftFront->x,                                           topLeftFront->y,                                           topLeftFront->z,                                           midx,                                           midy,                                           midz);            }             else if (pos == TopRightFront) {                children[pos] = new Octree(midx + 1,                                           topLeftFront->y,                                           topLeftFront->z,                                           bottomRightBack->x,                                           midy,                                           midz);            }            else if (pos == BottomRightFront) {                children[pos] = new Octree(midx + 1,                                           midy + 1,                                           topLeftFront->z,                                           bottomRightBack->x,                                           bottomRightBack->y,                                           midz);            }            else if (pos == BottomLeftFront) {                children[pos] = new Octree(topLeftFront->x,                                           midy + 1,                                           topLeftFront->z,                                           midx,                                           bottomRightBack->y,                                           midz);            }            else if (pos == TopLeftBottom) {                children[pos] = new Octree(topLeftFront->x,                                           topLeftFront->y,                                           midz + 1,                                           midx,                                           midy,                                           bottomRightBack->z);            }            else if (pos == TopRightBottom) {                children[pos] = new Octree(midx + 1,                                           topLeftFront->y,                                           midz + 1,                                           bottomRightBack->x,                                           midy,                                           bottomRightBack->z);            }            else if (pos == BottomRightBack) {                children[pos] = new Octree(midx + 1,                                           midy + 1,                                           midz + 1,                                           bottomRightBack->x,                                           bottomRightBack->y,                                           bottomRightBack->z);            }            else if (pos == BottomLeftBack) {                children[pos] = new Octree(topLeftFront->x,                                           midy + 1,                                           midz + 1,                                           midx,                                           bottomRightBack->y,                                           bottomRightBack->z);            }            children[pos]->insert(x_, y_, z_);            children[pos]->insert(x, y, z);        }    }     // Function that returns true if the point    // (x, y, z) exists in the octree    bool find(int x, int y, int z)    {        // If point is out of bound        if (x < topLeftFront->x            || x > bottomRightBack->x            || y < topLeftFront->y            || y > bottomRightBack->y            || z < topLeftFront->z            || z > bottomRightBack->z)            return 0;         // Otherwise perform binary search        // for each ordinate        int midx = (topLeftFront->x                    + bottomRightBack->x)                   / 2;        int midy = (topLeftFront->y                    + bottomRightBack->y)                   / 2;        int midz = (topLeftFront->z                    + bottomRightBack->z)                   / 2;         int pos = -1;         // Deciding the position        // where to move        if (x <= midx) {            if (y <= midy) {                if (z <= midz)                    pos = TopLeftFront;                else                    pos = TopLeftBottom;            }            else {                if (z <= midz)                    pos = BottomLeftFront;                else                    pos = BottomLeftBack;            }        }        else {            if (y <= midy) {                if (z <= midz)                    pos = TopRightFront;                else                    pos = TopRightBottom;            }            else {                if (z <= midz)                    pos = BottomRightFront;                else                    pos = BottomRightBack;            }        }         // If an internal node is encountered        if (children[pos]->point == nullptr) {            return children[pos]->find(x, y, z);        }         // If an empty node is encountered        else if (children[pos]->point->x == -1) {            return 0;        }        else {             // If node is found with            // the given value            if (x == children[pos]->point->x                && y == children[pos]->point->y                && z == children[pos]->point->z)                return 1;        }        return 0;    }}; // Driver codeint main(){    Octree tree(1, 1, 1, 5, 5, 5);     tree.insert(1, 2, 3);    tree.insert(1, 2, 3);    tree.insert(6, 5, 5);     cout << (tree.find(1, 2, 3)                 ? "Found\n"                 : "Not Found\n");     cout << (tree.find(3, 4, 4)                 ? "Found\n"                 : "Not Found\n");    tree.insert(3, 4, 4);     cout << (tree.find(3, 4, 4)                 ? "Found\n"                 : "Not Found\n");     return 0;}
Point already exist in the tree
Point is out of bound
found
not found
found
 
It is used in 3D computer graphics gamesIt is also used to find nearest neighboring objects in 3D spaceIt is also used for color quantization
It is used in 3D computer graphics games
It is also used to find nearest neighboring objects in 3D space
It is also used for color quantization
surindertarika1234
sumitgumber28
Octree
Advanced Data Structure
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Agents in Artificial Intelligence
Decision Tree Introduction with example
AVL Tree | Set 2 (Deletion)
Red-Black Tree | Set 2 (Insert)
Segment Tree | Set 1 (Sum of given range)
Disjoint Set Data Structures
Insert Operation in B-Tree
How to design a tiny URL or URL shortener?
Design a Chess Game