首先放图:
可以添加测试矩形,可以自定义添加点,点击测试按钮,可以判断点是否在矩形内,通过四叉树数据结构实现上述功能。
本人V:860472025,有任何Qt、C++开发问题可以联系我,不免费哦,但价格很低!!
template<typename T>
struct Point {
T x;
T y;
Point() {}
Point(T _x, T _y) :x(_x), y(_y) {}
};
template<typename T>
struct Node {
Node* R[4]; // 存储四个子节点的指针
Point<T> pt; // 存储点坐标
Node* parent; // 存储父节点的指针
};
template<typename ElemType>
class QuardTree
{
public:
QuardTree();
~QuardTree();
void Insert(const Point<ElemType>& pos); // 插入节点
void BalanceInsert(const Point<ElemType>& pos); // 平衡插入节点
int nodeCount(); // 获取节点数
int TPLS(); // 获取树的深度
int Height(); // 获取树的高度
void RegionResearch(ElemType left, ElemType right, ElemType botom, ElemType top, int& visitednum, int& foundnum); // 区域搜索
void clear(); // 清除所有节点
vector<Point<ElemType>> m_FinedPoint;
private:
Node<ElemType>* root; // 根节点指针
int Compare(const Node<ElemType>* node, const Point<ElemType>& pos); // 比较节点位置
bool In_Region(Point<ElemType> t, ElemType left, ElemType right, ElemType botom, ElemType top); // 检查点是否在区域内
bool Rectangle_Overlapse_Region(ElemType L, ElemType R, ElemType B, ElemType T, ElemType left, ElemType right, ElemType botom, ElemType top); // 检查矩形是否重叠
void RegionResearch(Node<ElemType>* t, ElemType left, ElemType right, ElemType botom, ElemType top, int& visitednum, int& foundnum); // 递归区域搜索
int Depth(Node<ElemType>*&); // 计算节点深度
int nodeCount(const Node<ElemType>*); // 计算节点数
void clear(Node < ElemType>*& p); // 递归清除节点
void Insert(Node<ElemType>*&, const Point<ElemType>& pos);//递归插入节点
};
template<typename T>
QuardTree<T>::QuardTree()
{
root = NULL; // 初始化根节点为空
}
template<typename T>
QuardTree<T>::~QuardTree()
{
clear(root);
}
template<typename T>
int QuardTree<T>::TPLS()
{
return Depth(root);
}
template<typename T>
int QuardTree<T>::Compare(const Node<T>* node, const Point<T>& pos)
{
if (pos.x == node->pt.x && pos.y == node->pt.y) return 0; // 节点位置相同
if (pos.x >= node->pt.x && pos.y > node->pt.y) return 1; // 节点在第一象限
if (pos.x < node->pt.x && pos.y >= node->pt.y) return 2; // 节点在第二象限
if (pos.x <= node->pt.x && pos.y < node->pt.y) return 3; // 节点在第三象限
if (pos.x > node->pt.x && pos.y <= node->pt.y) return 4; // 节点在第四象限
return -1; // 不可能的情况
}
template<typename T>
void QuardTree<T>::BalanceInsert(const Point<T>& pos)
{
Node<T>* node = (Node<T>*)malloc(sizeof(Node<T>)); // 分配新节点内存
node->R[0] = NULL;
node->R[1] = NULL;
node->R[2] = NULL;
node->R[3] = NULL;
node->parent = NULL;
node->pt = pos; // 设置新节点位置
if (root == NULL) {
root = node; // 如果根节点为空,将新节点设为根节点
return;
}
Node<T>* temp = root;
int direction = Compare(temp, pos);
if (direction == 0) return; // 节点已存在
while (temp->R[direction - 1] != NULL) {
temp = temp->R[direction - 1]; // 找到插入位置
direction = Compare(temp, pos);
if (direction == 0) return; // 节点已存在
}
temp->R[direction - 1] = node;
node->parent = temp; // 插入新节点
Node<T>* tp = temp->parent;
if (tp == NULL) return;
int r = Compare(tp, temp->pt);
if (abs(direction - r) == 2) {
Node<T>* leaf = node;
if (tp->R[abs(3 - r)] == NULL) {
tp->R[r - 1] = NULL;
temp->parent = leaf;
leaf->R[r - 1] = temp;
temp->R[abs(3 - r)] = NULL;
Node<T>* Rt = tp->parent;
if (Rt == NULL) {
root = leaf;
leaf->parent = NULL;
leaf->R[abs(3 - r)] = tp;
tp->parent = leaf;
return;
}
tp->parent = NULL;
int dd = Compare(Rt, tp->pt);
Rt->R[dd - 1] = leaf;
leaf->parent = Rt;
leaf->R[abs(3 - r)] = tp;
tp->parent = leaf;
}
}
}
template<typename T>
void QuardTree<T>::Insert(Node<T>*& p, const Point<T>& pos)
{
if (p == NULL)
{
Node<T>* node = (Node<T>*)malloc(sizeof(Node<T>)); // 分配新节点内存
node->R[0] = NULL;
node->R[1] = NULL;
node->R[2] = NULL;
node->R[3] = NULL;
node->pt = pos;
p = node;
return;
}
else
{
int d = Compare(p, pos);
if (d == 0) return;
Insert(p->R[d - 1], pos);
}
}
template<typename T>
void QuardTree<T>::Insert(const Point<T>& pos)
{
int direction, len = 0;
Node<T>* node = (Node<T>*)malloc(sizeof(Node<T>)); // 分配新节点内存
node->R[0] = NULL;
node->R[1] = NULL;
node->R[2] = NULL;
node->R[3] = NULL;
node->pt = pos; // 插入新节点
if (root == NULL)
{
root = node;
return;
}
direction = Compare(root, pos);
Node<T>* temp = root;
if (direction == 0) return;//节点已存在
len = 1;
while (temp->R[direction - 1] != NULL)
{
temp = temp->R[direction - 1]; // 找到插入位置
direction = Compare(temp, pos);
if (direction == 0) return; // 节点已存在
}
temp->R[direction - 1] = node; // 插入新节点
//Insert(root, pos);//递归插入节点
}