From 5c8e0539eeecad7987a2678e7db89a389ca205e9 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 16 Mar 2025 13:56:16 +0100 Subject: [PATCH] WIP (quad tree) --- src/db/db/dbQuadTree.h | 119 ++++++++++++++++++++++- src/db/unit_tests/dbQuadTreeTests.cc | 135 +++++++++++++++++++++++++++ 2 files changed, 249 insertions(+), 5 deletions(-) diff --git a/src/db/db/dbQuadTree.h b/src/db/db/dbQuadTree.h index 353f7ddcd..93674ea69 100644 --- a/src/db/db/dbQuadTree.h +++ b/src/db/db/dbQuadTree.h @@ -44,16 +44,77 @@ public: quad_tree_node (const point_type ¢er) : m_split (false), m_center (center) { - for (unsigned int i = 0; i < 4; ++i) { - m_q [i] = 0; - } + init (); } ~quad_tree_node () { + clear (); + } + + quad_tree_node (const quad_tree_node &other) + : m_split (false), m_center (center) + { + init (); + operator= (other); + } + + quad_tree_node &operator= (const quad_tree_node &other) + { + if (this != &other) { + clear (); + m_split = other.m_split; + m_center = other.m_center; + m_objects = other.m_objects; + for (unsigned int i = 0; i < 4; ++i) { + if (other.m_q[i]) { + m_q[i] = other.m_q[i]->clone (); + } + } + } + return *this; + } + + quad_tree_node (quad_tree_node &&other) + { + init (); + swap (other); + } + + quad_tree_node &operator= (quad_tree_node &&other) + { + swap (other); + return *this; + } + + void swap (quad_tree_node &other) + { + if (this != &other) { + std::swap (m_center, other.m_center); + std::swap (m_split, other.m_split); + m_objects.swap (other.m_objects); + for (unsigned int i = 0; i < 4; ++i) { + std::swap (m_q[i], other.m_q[i]); + } + } + } + + quad_tree_node *clone () const + { + quad_tree_node *node = new quad_tree_node (m_center); + *node = *this; + return node; + } + + void clear () + { + m_objects.clear (); + m_split = false; for (unsigned int i = 0; i < 4; ++i) { - delete m_q [i]; - m_q [i] = 0; + if (m_q[i]) { + delete m_q[i]; + } + m_q[i] = 0; } } @@ -163,6 +224,13 @@ private: quad_tree_node *m_q [4]; objects_vector m_objects; + void init () + { + for (unsigned int i = 0; i < 4; ++i) { + m_q[i] = 0; + } + } + int quad_for (const box_type &box) const { int sx = coord_traits::less (box.right (), m_center.x ()) ? 0 : (coord_traits::less (m_center.x (), box.left ()) ? 1 : -1); @@ -521,6 +589,47 @@ public: // .. nothing yet .. } + quad_tree (const quad_tree &other) + : m_root (point_type ()) + { + operator= (other); + } + + quad_tree &operator= (const quad_tree &other) + { + if (this != &other) { + m_root = other.m_root; + m_total_box = other.m_total_box; + } + return *this; + } + + quad_tree (quad_tree &&other) + : m_root (point_type ()) + { + swap (other); + } + + quad_tree &operator= (quad_tree &&other) + { + swap (other); + return *this; + } + + void clear () + { + m_root.clear (); + m_total_box = box_type (); + } + + void swap (quad_tree &other) + { + if (this != &other) { + m_root.swap (other.m_root); + std::swap (m_total_box, m_total_box); + } + } + bool empty () const { return m_root.empty (); diff --git a/src/db/unit_tests/dbQuadTreeTests.cc b/src/db/unit_tests/dbQuadTreeTests.cc index 62eec169e..6d39ea49b 100644 --- a/src/db/unit_tests/dbQuadTreeTests.cc +++ b/src/db/unit_tests/dbQuadTreeTests.cc @@ -256,3 +256,138 @@ TEST(remove) EXPECT_EQ (tree.levels (), size_t (1)); } +TEST(clear) +{ + 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.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)"); + + tree.clear (); + + EXPECT_EQ (tree.check (), true); + EXPECT_EQ (tree.empty (), true); + EXPECT_EQ (tree.size (), size_t (0)); + EXPECT_EQ (tree.levels (), size_t (1)); + EXPECT_EQ (find_all (tree), ""); +} + +TEST(copy) +{ + 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.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)"); + EXPECT_EQ (tree.levels (), size_t (2)); + + my_quad_tree tree2 (tree); + tree.clear (); + + EXPECT_EQ (tree2.check (), true); + EXPECT_EQ (find_all (tree2), "(-1,-2;3,4)/(-1,-3;-0.5,-2)/(-1,-3;-0.5,2)/(-1,-3;3,0)"); + EXPECT_EQ (tree2.levels (), size_t (2)); +} + +TEST(assign) +{ + 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.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)"); + EXPECT_EQ (tree.levels (), size_t (2)); + + my_quad_tree tree2; + tree2 = tree; + tree.clear (); + + EXPECT_EQ (tree2.check (), true); + EXPECT_EQ (find_all (tree2), "(-1,-2;3,4)/(-1,-3;-0.5,-2)/(-1,-3;-0.5,2)/(-1,-3;3,0)"); + EXPECT_EQ (tree2.levels (), size_t (2)); +} + +TEST(swap) +{ + 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.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)"); + EXPECT_EQ (tree.levels (), size_t (2)); + + my_quad_tree tree2; + tree2.swap (tree); + + EXPECT_EQ (tree.check (), true); + EXPECT_EQ (tree.empty (), true); + EXPECT_EQ (find_all (tree), ""); + EXPECT_EQ (tree.levels (), size_t (1)); + + EXPECT_EQ (tree2.check (), true); + EXPECT_EQ (find_all (tree2), "(-1,-2;3,4)/(-1,-3;-0.5,-2)/(-1,-3;-0.5,2)/(-1,-3;3,0)"); + EXPECT_EQ (tree2.levels (), size_t (2)); +} + +TEST(move) +{ + 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.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)"); + EXPECT_EQ (tree.levels (), size_t (2)); + + my_quad_tree tree2; + tree2 = std::move (tree); + + EXPECT_EQ (tree.check (), true); + EXPECT_EQ (tree.empty (), true); + EXPECT_EQ (find_all (tree), ""); + EXPECT_EQ (tree.levels (), size_t (1)); + + EXPECT_EQ (tree2.check (), true); + EXPECT_EQ (find_all (tree2), "(-1,-2;3,4)/(-1,-3;-0.5,-2)/(-1,-3;-0.5,2)/(-1,-3;3,0)"); + EXPECT_EQ (tree2.levels (), size_t (2)); +} + +TEST(move_ctor) +{ + 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.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)"); + EXPECT_EQ (tree.levels (), size_t (2)); + + my_quad_tree tree2 (std::move (tree)); + + EXPECT_EQ (tree.check (), true); + EXPECT_EQ (tree.empty (), true); + EXPECT_EQ (find_all (tree), ""); + EXPECT_EQ (tree.levels (), size_t (1)); + + EXPECT_EQ (tree2.check (), true); + EXPECT_EQ (find_all (tree2), "(-1,-2;3,4)/(-1,-3;-0.5,-2)/(-1,-3;-0.5,2)/(-1,-3;3,0)"); + EXPECT_EQ (tree2.levels (), size_t (2)); +} +