#include <iostream>
#include <vector>
class GFG {
public:
double x;
double y;
GFG(double x, double y)
: x(x)
, y(y)
{
}
};
class Quadtree {
private:
static const int MAX_CAPACITY = 4;
static const int MAX_DEPTH = 10;
class QuadtreeNode {
public:
double xMin;
double yMin;
double xMax;
double yMax;
std::vector<GFG> points;
QuadtreeNode* nw;
QuadtreeNode* ne;
QuadtreeNode* sw;
QuadtreeNode* se;
QuadtreeNode(double xMin, double yMin, double xMax,
double yMax)
: xMin(xMin)
, yMin(yMin)
, xMax(xMax)
, yMax(yMax)
, nw(nullptr)
, ne(nullptr)
, sw(nullptr)
, se(nullptr)
{
}
};
QuadtreeNode* root;
void insertHelper(QuadtreeNode* node, const GFG& point,
int depth);
void queryRangeHelper(QuadtreeNode* node,
const double& xMin,
const double& yMin,
const double& xMax,
const double& yMax,
std::vector<GFG>& result) const;
public:
Quadtree(double xMin, double yMin, double xMax,
double yMax);
~Quadtree();
void insert(const GFG& point);
std::vector<GFG> queryRange(const double& xMin,
const double& yMin,
const double& xMax,
const double& yMax) const;
};
Quadtree::Quadtree(double xMin, double yMin, double xMax,
double yMax)
{
root = new QuadtreeNode(xMin, yMin, xMax, yMax);
}
Quadtree::~Quadtree() {}
void Quadtree::insertHelper(QuadtreeNode* node,
const GFG& point, int depth)
{
if (depth >= MAX_DEPTH || node == nullptr)
return;
if (node->points.size() < MAX_CAPACITY) {
node->points.push_back(point);
}
else {
double xMid = (node->xMin + node->xMax) / 2.0;
double yMid = (node->yMin + node->yMax) / 2.0;
if (point.x <= xMid) {
if (point.y <= yMid) {
if (node->nw == nullptr)
node->nw = new QuadtreeNode(
node->xMin, node->yMin, xMid, yMid);
insertHelper(node->nw, point, depth + 1);
}
else {
if (node->sw == nullptr)
node->sw = new QuadtreeNode(
node->xMin, yMid, xMid, node->yMax);
insertHelper(node->sw, point, depth + 1);
}
}
else {
if (point.y <= yMid) {
if (node->ne == nullptr)
node->ne = new QuadtreeNode(
xMid, node->yMin, node->xMax, yMid);
insertHelper(node->ne, point, depth + 1);
}
else {
if (node->se == nullptr)
node->se = new QuadtreeNode(
xMid, yMid, node->xMax, node->yMax);
insertHelper(node->se, point, depth + 1);
}
}
}
}
void Quadtree::insert(const GFG& point)
{
insertHelper(root, point, 0);
}
void Quadtree::queryRangeHelper(
QuadtreeNode* node, const double& xMin,
const double& yMin, const double& xMax,
const double& yMax, std::vector<GFG>& result) const
{
if (node == nullptr)
return;
for (const GFG& point : node->points) {
if (point.x >= xMin && point.x <= xMax
&& point.y >= yMin && point.y <= yMax)
result.push_back(point);
}
double xMid = (node->xMin + node->xMax) / 2.0;
double yMid = (node->yMin + node->yMax) / 2.0;
if (xMin <= xMid && yMin <= yMid)
queryRangeHelper(node->nw, xMin, yMin, xMax, yMax,
result);
if (xMin <= xMid && yMax >= yMid)
queryRangeHelper(node->sw, xMin, yMin, xMax, yMax,
result);
if (xMax >= xMid && yMin <= yMid)
queryRangeHelper(node->ne, xMin, yMin, xMax, yMax,
result);
if (xMax >= xMid && yMax >= yMid)
queryRangeHelper(node->se, xMin, yMin, xMax, yMax,
result);
}
std::vector<GFG>
Quadtree::queryRange(const double& xMin, const double& yMin,
const double& xMax,
const double& yMax) const
{
std::vector<GFG> result;
queryRangeHelper(root, xMin, yMin, xMax, yMax, result);
return result;
}
int main()
{
Quadtree quadtree(0.0, 0.0, 100.0, 100.0);
quadtree.insert(GFG(20.0, 30.0));
quadtree.insert(GFG(40.0, 50.0));
quadtree.insert(GFG(60.0, 70.0));
quadtree.insert(GFG(80.0, 90.0));
std::vector<GFG> pointsInRange
= quadtree.queryRange(0.0, 0.0, 90.0, 90.0);
for (const GFG& point : pointsInRange) {
std::cout << "Point: (" << point.x << ", "
<< point.y << ")\n";
}
return 0;
}