WIP (quad tree)

This commit is contained in:
Matthias Koefferlein 2025-03-16 14:46:03 +01:00
parent 5c8e0539ee
commit f1f35ae2a4
2 changed files with 104 additions and 13 deletions

View File

@ -290,22 +290,26 @@ private:
}
box_type b = BC () (value);
int n = quad_for (b);
if (n < 0) {
m_objects.push_back (value);
return;
}
if (b.inside (box (ucenter))) {
if (! m_q[n]) {
box_type bq = q (n, ucenter);
m_q[n] = new quad_tree_node (bq.center ());
int n = quad_for (b);
if (n < 0) {
m_objects.push_back (value);
} else {
if (! m_q[n]) {
box_type bq = q (n, ucenter);
m_q[n] = new quad_tree_node (bq.center ());
}
m_q[n]->insert (value, m_center);
}
m_q[n]->insert (value, m_center);
} else {
grow (m_center - (m_center - ucenter) * 2.0);
insert (value, ucenter);
tl_assert (m_q[0] || m_q[1] || m_q[2] || m_q[3]);
point_type new_ucenter = m_center - (m_center - ucenter) * 2.0;
grow (new_ucenter);
insert (value, new_ucenter);
}
}
@ -317,6 +321,7 @@ private:
if (m_q[i]) {
quad_tree_node *n = m_q[i];
m_q[i] = new quad_tree_node (q (i, ucenter).center ());
m_q[i]->m_split = true;
m_q[i]->m_q[3 - i] = n;
}
}
@ -470,6 +475,8 @@ public:
while (! m_stack.empty ()) {
qn = m_stack.back ().first;
int &n = m_stack.back ().second;
while (++n < 4) {
box_type bq = qn->q_box (n);

View File

@ -26,6 +26,8 @@
#include "tlUnitTest.h"
#include "tlString.h"
#include <stdlib.h>
typedef db::quad_tree<db::DBox, db::box_convert<db::DBox>, size_t (1)> my_quad_tree;
std::string find_all (const my_quad_tree &qt)
@ -256,6 +258,58 @@ TEST(remove)
EXPECT_EQ (tree.levels (), size_t (1));
}
TEST(grow)
{
my_quad_tree tree;
tree.insert (db::DBox (-1, -2, 3, 4));
tree.insert (db::DBox (-1, -3, 3, 0));
tree.insert (db::DBox (-1, -3, -0.5, -2));
tree.insert (db::DBox (-1, -3, -0.5, 2));
EXPECT_EQ (tree.levels (), size_t (2));
tree.insert (db::DBox (-100, -3, -99, 2));
EXPECT_EQ (tree.levels (), size_t (8));
EXPECT_EQ (tree.check (), true);
EXPECT_EQ (find_all (tree), "(-1,-2;3,4)/(-1,-3;-0.5,-2)/(-1,-3;-0.5,2)/(-1,-3;3,0)/(-100,-3;-99,2)");
EXPECT_EQ (find_overlapping (tree, db::DBox (-100, -100, -90, 100)), "(-100,-3;-99,2)");
bool r = true;
while (r && ! tree.empty ()) {
r = tree.erase (*tree.begin ());
EXPECT_EQ (r, true);
EXPECT_EQ (tree.check (), true);
}
EXPECT_EQ (tree.size (), size_t (0));
EXPECT_EQ (tree.levels (), size_t (1));
}
TEST(grow2)
{
my_quad_tree tree;
tree.insert (db::DBox (-1, -2, 3, 4));
tree.insert (db::DBox (-1, -3, 3, 0));
tree.insert (db::DBox (-1, -3, -0.5, -2));
tree.insert (db::DBox (-1, -3, -0.5, 2));
EXPECT_EQ (tree.levels (), size_t (2));
tree.insert (db::DBox (-100, -3, -99, -1));
EXPECT_EQ (tree.levels (), size_t (8));
EXPECT_EQ (tree.check (), true);
EXPECT_EQ (find_all (tree), "(-1,-2;3,4)/(-1,-3;-0.5,-2)/(-1,-3;-0.5,2)/(-1,-3;3,0)/(-100,-3;-99,-1)");
EXPECT_EQ (find_overlapping (tree, db::DBox (-100, -100, -90, 100)), "(-100,-3;-99,-1)");
bool r = true;
while (r && ! tree.empty ()) {
r = tree.erase (*tree.begin ());
EXPECT_EQ (r, true);
EXPECT_EQ (tree.check (), true);
}
EXPECT_EQ (tree.size (), size_t (0));
EXPECT_EQ (tree.levels (), size_t (1));
}
TEST(clear)
{
my_quad_tree tree;
@ -391,3 +445,33 @@ TEST(move_ctor)
EXPECT_EQ (tree2.levels (), size_t (2));
}
static double rvalue ()
{
return ((rand () % 1000000) - 5000) * 0.001;
}
static db::DBox rbox ()
{
return db::DBox (db::DPoint (rvalue (), rvalue ()), db::DPoint (rvalue (), rvalue ()));
}
TEST(many)
{
return; // @@@
my_quad_tree tree;
unsigned int n = 1000;
for (unsigned int i = 0; i < n; ++i) {
tree.insert (rbox ());
}
EXPECT_EQ (tree.check (), true);
bool r = true;
while (r && ! tree.empty ()) {
r = tree.erase (*tree.begin ());
EXPECT_EQ (r, true);
EXPECT_EQ (tree.check (), true);
}
}