//待完善
#include<iostream>
#include<vector>
#include <algorithm>
#include <set>
using namespace std;
//象限位置
enum QuadRant
{
TOPR,
TOPL,
BOTTL,
BOTTR
};
struct QuadRect
{
double top;
double left;
double right;
double bottom;
double midH;
double midV;
QuadRect() {}
QuadRect(double _top, double _left, double _right, double _bottom)
{
top = _top;
left = _left;
right = _right;
bottom = _bottom;
midH = (_top + _bottom) / 2;
midV = (_left + _right) / 2;
}
bool operator== (QuadRect& rect)
{
return rect.top == top
&& rect.bottom == bottom
&& rect.right == right
&& rect.left == left;
}
};
struct QuadNode
{
public:
QuadRect rect;
vector<QuadRect>* container;
QuadNode* children[4];
int childCount;
QuadNode(QuadRect _rect)
{
rect = _rect;
container = new vector<QuadRect>();
childCount = 0;
for (int i = 0; i < 4; ++i)
children[i] = nullptr;
}
~QuadNode()
{
if (container)
delete container;
container = nullptr;
for (int i = 0; i < 4; ++i)
{
if (children[i])
delete children[i];
children[i] = nullptr;
}
}
};
struct QuadTrie
{
private:
QuadNode* root;
//value 在区间内
bool isInSection(double start, double end, double value)
{
return value >= start && value <= end;
}
//获取目标象限Rect
QuadRect getRect(QuadRect rect, QuadRant target)
{
switch (target)
{
case TOPR:
return QuadRect(rect.top, rect.midV, rect.right, rect.midH);
case TOPL:
return QuadRect(rect.top, rect.left, rect.midV, rect.midH);
case BOTTL:
return QuadRect(rect.midH, rect.left, rect.midV, rect.bottom);
case BOTTR:
return QuadRect(rect.midH, rect.midV, rect.right, rect.bottom);
}
}
//向子节点插入
void insertBranch(QuadNode* node, QuadRect& _rect)
{
int section = checkQuad(node->rect, _rect);
for (int i = 0; i < 4; ++i)
{
if ((section >> i) & 1)
{
if (node->children[i] == nullptr)
node->children[i] = new QuadNode(getRect(node->rect, (QuadRant)i));
insert(node->children[i], _rect);
}
}
}
// 1 << 0位是第一象限, 1 << 1位是第二象限, 依次类推
int checkQuad(QuadRect& target,QuadRect& _rect)
{
int ret = 0;
// 一二象限
if (isInSection(target.midH, target.top, _rect.bottom)
|| isInSection(target.midH, target.top, _rect.top))
{
//第一象限
if (isInSection(target.midV, target.right, _rect.right)
|| isInSection(target.midV, target.right, _rect.left))
ret |= (1 << 0);
//第二象限
if (isInSection(target.left, target.midV, _rect.right)
|| isInSection(target.left, target.midV, _rect.left))
ret |= (1 << 1);
}
// 三四象限
if (isInSection(target.bottom, target.midH, _rect.bottom)
|| isInSection(target.bottom, target.midH, _rect.top))
{
//第三象限
if (isInSection(target.left, target.midV, _rect.right)
|| isInSection(target.left, target.midV, _rect.left))
ret |= (1 << 2);
//第四象限
if (isInSection(target.midV, target.right, _rect.right)
|| isInSection(target.midV, target.right, _rect.left))
ret |= (1 << 3);
}
return ret;
}
public:
QuadTrie(QuadRect rect)
{
root = new QuadNode(rect);
}
~QuadTrie()
{
delete root;
}
void insert(QuadRect rect)
{
// 检查是否在范围内
if (checkQuad(root->rect, rect) == 0) return;
insert(root, rect);
}
void insert(QuadNode* node, QuadRect& _rect)
{
++node->childCount;
//小于三个时 就加入container
if (node->container && node->container->size() < 3)
{
node->container->push_back(_rect);
return;
}
//创建已有分支并销毁container
if (node->container)
{
for (QuadRect& ele : *node->container)
{
insertBranch(node, ele);
}
delete node->container;
node->container = nullptr;
}
insertBranch(node, _rect);
}
}