6std::vector<int> QuadTree::emptyBlock = {};
9 const double hx,
const double hy)
10 : m_x0(x0), m_y0(y0), m_hx(hx), m_hy(hy) {
17 for (
size_t i = 0; i < 4; ++i) children[i] =
nullptr;
21 for (
size_t i = 0; i < 4; ++i)
delete children[i];
24bool QuadTree::DoesBoxOverlap(
const double bb[4])
const {
25 if (m_xmax < bb[0] || m_ymax < bb[1])
return false;
26 if (m_xmin > bb[2] || m_ymin > bb[3])
return false;
30int QuadTree::GetQuadrant(
const double x,
const double y)
const {
32 if (x >= m_x0) quad |= 2;
33 if (y >= m_y0) quad |= 1;
37bool QuadTree::IsLeafNode()
const {
40 return children[0] ==
nullptr;
48 int quad = GetQuadrant(x, y);
49 children[quad]->InsertMeshNode(x, y, index);
54 if (nodes.size() < BlockCapacity) {
55 nodes.push_back(std::make_tuple(x, y, index));
60 for (
int i = 0; i < 4; ++i) {
62 const double xi = m_x0 + m_hx * (i & 2 ? 0.5 : -0.5);
63 const double yi = m_y0 + m_hy * (i & 1 ? 0.5 : -0.5);
64 children[i] =
new QuadTree(xi, yi, 0.5 * m_hx, 0.5 * m_hy);
69 while (!nodes.empty()) {
70 auto node = nodes.back();
72 const double xn = std::get<0>(node);
73 const double yn = std::get<1>(node);
74 const int quad = GetQuadrant(xn, yn);
75 children[quad]->InsertMeshNode(xn, yn, std::get<2>(node));
78 children[GetQuadrant(x, y)]->InsertMeshNode(x, y, index);
84 elements.push_back(index);
88 for (
int i = 0; i < 4; ++i) {
89 if (!children[i]->DoesBoxOverlap(bb))
continue;
90 children[i]->InsertMeshElement(bb, index);
95 const double y)
const {
96 const auto node = GetBlockFromPoint(x, y);
97 return node ? node->elements : emptyBlock;
100const QuadTree* QuadTree::GetBlockFromPoint(
101 const double x,
const double y)
const {
102 if (x < m_xmin || x > m_xmax || y < m_ymin || y > m_ymax) {
105 return GetBlockFromPointHelper(x, y);
108const QuadTree* QuadTree::GetBlockFromPointHelper(
109 const double x,
const double y)
const {
111 if (IsLeafNode())
return this;
113 int quad = GetQuadrant(x, y);
114 return children[quad]->GetBlockFromPointHelper(x, y);
QuadTree(const double x0, const double y0, const double hx, const double hy)
Constructor.
void InsertMeshElement(const double bb[4], const int index)
Insert a mesh element with given bounding box and index to the tree.
void InsertMeshNode(const double x, const double y, const int index)
Insert a mesh node (a vertex/point) to the tree.
const std::vector< int > & GetElementsInBlock(const double x, const double y) const
Get all elements linked to a block corresponding to the given point.