mirror of
https://github.com/KLayout/klayout.git
synced 2026-08-22 05:57:41 +02:00
WIP (quad tree)
This commit is contained in:
+126
-30
@@ -24,6 +24,7 @@
|
|||||||
#define HDR_dbQuadTree
|
#define HDR_dbQuadTree
|
||||||
|
|
||||||
#include "dbBox.h"
|
#include "dbBox.h"
|
||||||
|
#include "tlLog.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace db
|
namespace db
|
||||||
@@ -38,6 +39,7 @@ public:
|
|||||||
typedef db::point<coord_type> point_type;
|
typedef db::point<coord_type> point_type;
|
||||||
typedef db::vector<coord_type> vector_type;
|
typedef db::vector<coord_type> vector_type;
|
||||||
typedef std::vector<T> objects_vector;
|
typedef std::vector<T> objects_vector;
|
||||||
|
typedef db::coord_traits<coord_type> coord_traits;
|
||||||
|
|
||||||
quad_tree_node (const point_type ¢er)
|
quad_tree_node (const point_type ¢er)
|
||||||
: m_split (false), m_center (center)
|
: m_split (false), m_center (center)
|
||||||
@@ -65,23 +67,31 @@ public:
|
|||||||
insert (value, propose_ucenter (total_box));
|
insert (value, propose_ucenter (total_box));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool remove (const T &value)
|
bool erase (const T &value)
|
||||||
{
|
{
|
||||||
box_type b = BC () (value);
|
box_type b = BC () (value);
|
||||||
|
|
||||||
if (! m_split || b.contains (m_center)) {
|
int n = quad_for (b);
|
||||||
|
|
||||||
|
if (! m_split || n < 0) {
|
||||||
|
|
||||||
for (auto i = m_objects.begin (); i != m_objects.end (); ++i) {
|
for (auto i = m_objects.begin (); i != m_objects.end (); ++i) {
|
||||||
if (*i == value) {
|
if (*i == value) {
|
||||||
m_objects.erase (i);
|
m_objects.erase (i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 4; ++i) {
|
} else if (m_q[n]) {
|
||||||
if (m_q[i] && b.inside (m_q[i]->box (m_center))) {
|
|
||||||
return b.remove (value);
|
if (m_q[n]->erase (value)) {
|
||||||
|
if (m_q[n]->empty ()) {
|
||||||
|
delete m_q[n];
|
||||||
|
m_q[n] = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -131,12 +141,39 @@ public:
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t levels () const
|
||||||
|
{
|
||||||
|
size_t l = 1;
|
||||||
|
for (unsigned int n = 0; n < 4; ++n) {
|
||||||
|
if (m_q[n]) {
|
||||||
|
l = std::max (l, m_q[n]->levels () + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_top (const box_type &total_box) const
|
||||||
|
{
|
||||||
|
return check (propose_ucenter (total_box));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_split;
|
bool m_split;
|
||||||
point_type m_center;
|
point_type m_center;
|
||||||
quad_tree_node *m_q [4];
|
quad_tree_node *m_q [4];
|
||||||
objects_vector m_objects;
|
objects_vector m_objects;
|
||||||
|
|
||||||
|
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);
|
||||||
|
int sy = coord_traits::less (box.top (), m_center.y ()) ? 0 : (coord_traits::less (m_center.y (), box.bottom ()) ? 2 : -1);
|
||||||
|
if (sx < 0 || sy < 0) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return sx + sy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
box_type box (const point_type &ucenter) const
|
box_type box (const point_type &ucenter) const
|
||||||
{
|
{
|
||||||
return box_type (ucenter, ucenter - (ucenter - m_center) * 2.0);
|
return box_type (ucenter, ucenter - (ucenter - m_center) * 2.0);
|
||||||
@@ -185,33 +222,24 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
box_type b = BC () (value);
|
box_type b = BC () (value);
|
||||||
// @@@ should exclude m_center on box
|
int n = quad_for (b);
|
||||||
if (b.contains (m_center)) {
|
|
||||||
|
if (n < 0) {
|
||||||
m_objects.push_back (value);
|
m_objects.push_back (value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 4; ++i) {
|
if (b.inside (box (ucenter))) {
|
||||||
box_type bq = q (i, ucenter);
|
if (! m_q[n]) {
|
||||||
if (b.inside (bq)) {
|
box_type bq = q (n, ucenter);
|
||||||
if (! m_q[i]) {
|
m_q[n] = new quad_tree_node (bq.center ());
|
||||||
m_q[i] = new quad_tree_node (bq.center ());
|
|
||||||
}
|
|
||||||
m_q[i]->insert (value, m_center);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
m_q[n]->insert (value, m_center);
|
||||||
|
} else {
|
||||||
|
grow (m_center - (m_center - ucenter) * 2.0);
|
||||||
|
insert (value, ucenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 4; ++i) {
|
|
||||||
if (m_q[i]) {
|
|
||||||
grow (m_center - (m_center - m_q[i]->center ()) * 2.0);
|
|
||||||
insert (value, ucenter);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tl_assert (false);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,6 +266,61 @@ private:
|
|||||||
coord_type dy = std::max (std::abs (total_box.bottom () - m_center.y ()), std::abs (total_box.top () - m_center.y ()));
|
coord_type dy = std::max (std::abs (total_box.bottom () - m_center.y ()), std::abs (total_box.top () - m_center.y ()));
|
||||||
return m_center - vector_type (dx, dy);
|
return m_center - vector_type (dx, dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check (const point_type &ucenter) const
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
box_type bq = box (ucenter);
|
||||||
|
|
||||||
|
for (auto i = m_objects.begin (); i != m_objects.end (); ++i) {
|
||||||
|
box_type b = BC () (*i);
|
||||||
|
if (! b.inside (bq)) {
|
||||||
|
tl::error << "Box " << b.to_string () << " not inside quad box " << bq.to_string ();
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_split) {
|
||||||
|
|
||||||
|
for (auto i = m_objects.begin (); i != m_objects.end (); ++i) {
|
||||||
|
box_type b = BC () (*i);
|
||||||
|
int n = quad_for (b);
|
||||||
|
if (n >= 0) {
|
||||||
|
tl::error << "Box " << b.to_string () << " on quad level not overlapping multiple quads";
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int n = 0; n < 4; ++n) {
|
||||||
|
if (m_q[n]) {
|
||||||
|
m_q[n]->check (m_center);
|
||||||
|
box_type bbq = m_q[n]->box (m_center);
|
||||||
|
if (bbq != q (n, ucenter)) {
|
||||||
|
tl::error << "Quad not centered (quad box is " << bbq.to_string () << ", should be " << q (n, ucenter).to_string ();
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (m_objects.size () > thr) {
|
||||||
|
tl::error << "Non-split object count exceeds threshold " << m_objects.size () << " > " << thr;
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int n = 0; n < 4; ++n) {
|
||||||
|
if (m_q[n]) {
|
||||||
|
tl::error << "Non-split node has child nodes";
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class BC, size_t thr, class S>
|
template <class T, class BC, size_t thr, class S>
|
||||||
@@ -315,9 +398,9 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (! m_stack.empty ()) {
|
m_stack.pop_back ();
|
||||||
|
|
||||||
m_stack.pop_back ();
|
while (! m_stack.empty ()) {
|
||||||
|
|
||||||
int &n = m_stack.back ().second;
|
int &n = m_stack.back ().second;
|
||||||
while (++n < 4) {
|
while (++n < 4) {
|
||||||
@@ -329,6 +412,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_stack.pop_back ();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -415,6 +500,7 @@ private:
|
|||||||
box_type m_box;
|
box_type m_box;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// @@@ TODO: copy, assignment, move, swap
|
||||||
template <class T, class BC, size_t thr>
|
template <class T, class BC, size_t thr>
|
||||||
class quad_tree
|
class quad_tree
|
||||||
{
|
{
|
||||||
@@ -445,6 +531,16 @@ public:
|
|||||||
return m_root.size ();
|
return m_root.size ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t levels () const
|
||||||
|
{
|
||||||
|
return m_root.levels ();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check () const
|
||||||
|
{
|
||||||
|
return m_root.check_top (m_total_box);
|
||||||
|
}
|
||||||
|
|
||||||
void insert (const T &value)
|
void insert (const T &value)
|
||||||
{
|
{
|
||||||
box_type b = BC () (value);
|
box_type b = BC () (value);
|
||||||
@@ -456,9 +552,9 @@ public:
|
|||||||
m_root.insert_top (value, m_total_box);
|
m_root.insert_top (value, m_total_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
void erase (const T &value)
|
bool erase (const T &value)
|
||||||
{
|
{
|
||||||
m_root.remove (value);
|
return m_root.erase (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
quad_tree_flat_iterator begin () const
|
quad_tree_flat_iterator begin () const
|
||||||
|
|||||||
@@ -28,6 +28,18 @@
|
|||||||
|
|
||||||
typedef db::quad_tree<db::DBox, db::box_convert<db::DBox>, size_t (1)> my_quad_tree;
|
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)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
auto i = qt.begin ();
|
||||||
|
while (! i.at_end ()) {
|
||||||
|
v.push_back (i->to_string ());
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
std::sort (v.begin (), v.end ());
|
||||||
|
return tl::join (v, "/");
|
||||||
|
}
|
||||||
|
|
||||||
std::string find_touching (const my_quad_tree &qt, const db::DBox &box)
|
std::string find_touching (const my_quad_tree &qt, const db::DBox &box)
|
||||||
{
|
{
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
@@ -40,6 +52,20 @@ std::string find_touching (const my_quad_tree &qt, const db::DBox &box)
|
|||||||
return tl::join (v, "/");
|
return tl::join (v, "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string find_touching_from_all (const my_quad_tree &qt, const db::DBox &box)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
auto i = qt.begin ();
|
||||||
|
while (! i.at_end ()) {
|
||||||
|
if (i->touches (box)) {
|
||||||
|
v.push_back (i->to_string ());
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
std::sort (v.begin (), v.end ());
|
||||||
|
return tl::join (v, "/");
|
||||||
|
}
|
||||||
|
|
||||||
std::string find_overlapping (const my_quad_tree &qt, const db::DBox &box)
|
std::string find_overlapping (const my_quad_tree &qt, const db::DBox &box)
|
||||||
{
|
{
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
@@ -52,26 +78,181 @@ std::string find_overlapping (const my_quad_tree &qt, const db::DBox &box)
|
|||||||
return tl::join (v, "/");
|
return tl::join (v, "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string find_overlapping_from_all (const my_quad_tree &qt, const db::DBox &box)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
auto i = qt.begin ();
|
||||||
|
while (! i.at_end ()) {
|
||||||
|
if (i->overlaps (box)) {
|
||||||
|
v.push_back (i->to_string ());
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
std::sort (v.begin (), v.end ());
|
||||||
|
return tl::join (v, "/");
|
||||||
|
}
|
||||||
|
|
||||||
TEST(basic)
|
TEST(basic)
|
||||||
{
|
{
|
||||||
my_quad_tree tree;
|
my_quad_tree tree;
|
||||||
EXPECT_EQ (tree.empty (), true);
|
EXPECT_EQ (tree.empty (), true);
|
||||||
EXPECT_EQ (tree.size (), size_t (0));
|
EXPECT_EQ (tree.size (), size_t (0));
|
||||||
|
EXPECT_EQ (tree.check (), true);
|
||||||
|
EXPECT_EQ (tree.levels (), size_t (1));
|
||||||
|
|
||||||
tree.insert (db::DBox ());
|
tree.insert (db::DBox ());
|
||||||
EXPECT_EQ (tree.empty (), true);
|
EXPECT_EQ (tree.empty (), true);
|
||||||
EXPECT_EQ (tree.size (), size_t (0));
|
EXPECT_EQ (tree.size (), size_t (0));
|
||||||
|
EXPECT_EQ (tree.check (), true);
|
||||||
|
EXPECT_EQ (tree.levels (), size_t (1));
|
||||||
|
|
||||||
tree.insert (db::DBox (-1, -2, 3, 4));
|
tree.insert (db::DBox (-1, -2, 3, 4));
|
||||||
EXPECT_EQ (tree.empty (), false);
|
EXPECT_EQ (tree.empty (), false);
|
||||||
EXPECT_EQ (tree.size (), size_t (1));
|
EXPECT_EQ (tree.size (), size_t (1));
|
||||||
|
EXPECT_EQ (tree.check (), true);
|
||||||
|
EXPECT_EQ (tree.levels (), size_t (1));
|
||||||
|
|
||||||
EXPECT_EQ (find_touching (tree, db::DBox (-2, 0, -1, 0)), "...");
|
EXPECT_EQ (find_all (tree), "(-1,-2;3,4)");
|
||||||
|
|
||||||
|
db::DBox bx;
|
||||||
|
|
||||||
|
bx = db::DBox (-2, 0, -1, 0);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, -3, -1, -2);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, -3, -1, -2.5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 4, -1, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 4.5, -1, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 3, -1, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 3, -1.5, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
|
||||||
tree.insert (db::DBox (-1, -3, 3, 0));
|
tree.insert (db::DBox (-1, -3, 3, 0));
|
||||||
EXPECT_EQ (tree.empty (), false);
|
EXPECT_EQ (tree.empty (), false);
|
||||||
EXPECT_EQ (tree.size (), size_t (1));
|
EXPECT_EQ (tree.size (), size_t (2));
|
||||||
|
EXPECT_EQ (tree.check (), true);
|
||||||
|
EXPECT_EQ (tree.levels (), size_t (1));
|
||||||
|
|
||||||
EXPECT_EQ (find_touching (tree, db::DBox (-2, 0, -1, 0)), "...");
|
EXPECT_EQ (find_all (tree), "(-1,-2;3,4)/(-1,-3;3,0)");
|
||||||
|
|
||||||
|
bx = db::DBox (-2, 0, -1, 0);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, -3, -1, -2);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, -3, -1, -2.5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 4, -1, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 4.5, -1, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 3, -1, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 3, -1.5, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
|
||||||
|
tree.insert (db::DBox (-1, -3, -0.5, -2));
|
||||||
|
EXPECT_EQ (tree.empty (), false);
|
||||||
|
EXPECT_EQ (tree.size (), size_t (3));
|
||||||
|
EXPECT_EQ (tree.check (), true);
|
||||||
|
EXPECT_EQ (tree.levels (), size_t (2));
|
||||||
|
|
||||||
|
EXPECT_EQ (find_all (tree), "(-1,-2;3,4)/(-1,-3;-0.5,-2)/(-1,-3;3,0)");
|
||||||
|
|
||||||
|
bx = db::DBox (-2, 0, -1, 0);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, -3, -1, -2);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, -3, -1, -2.5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 4, -1, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 4.5, -1, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 3, -1, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 3, -1.5, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
|
||||||
|
tree.insert (db::DBox (-1, -3, -0.5, 2));
|
||||||
|
EXPECT_EQ (tree.empty (), false);
|
||||||
|
EXPECT_EQ (tree.size (), size_t (4));
|
||||||
|
EXPECT_EQ (tree.check (), true);
|
||||||
|
EXPECT_EQ (tree.levels (), size_t (2));
|
||||||
|
|
||||||
|
EXPECT_EQ (find_all (tree), "(-1,-2;3,4)/(-1,-3;-0.5,-2)/(-1,-3;-0.5,2)/(-1,-3;3,0)");
|
||||||
|
|
||||||
|
bx = db::DBox (-2, 0, -1, 0);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, -3, -1, -2);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, -3, -1, -2.5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 4, -1, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 4.5, -1, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 3, -1, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
bx = db::DBox (-2, 3, -1.5, 5);
|
||||||
|
EXPECT_EQ (find_touching (tree, bx), find_touching_from_all (tree, bx));
|
||||||
|
EXPECT_EQ (find_overlapping (tree, bx), find_overlapping_from_all (tree, bx));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(remove)
|
||||||
|
{
|
||||||
|
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.erase (db::DBox (-1, -3, -0.5, -1)), false);
|
||||||
|
EXPECT_EQ (tree.erase (db::DBox (-1, -3, -0.5, -2)), true);
|
||||||
|
EXPECT_EQ (tree.check (), true);
|
||||||
|
|
||||||
|
EXPECT_EQ (find_all (tree), "(-1,-2;3,4)/(-1,-3;-0.5,2)/(-1,-3;3,0)");
|
||||||
|
|
||||||
|
while (! tree.empty ()) {
|
||||||
|
EXPECT_EQ (tree.erase (*tree.begin ()), true);
|
||||||
|
EXPECT_EQ (tree.check (), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ (tree.size (), size_t (0));
|
||||||
|
EXPECT_EQ (tree.levels (), size_t (1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user