mirror of https://github.com/KLayout/klayout.git
WIP (quad tree)
This commit is contained in:
parent
f1f35ae2a4
commit
4369835e8b
|
|
@ -30,7 +30,7 @@
|
|||
namespace db
|
||||
{
|
||||
|
||||
template <class T, class BC, size_t thr>
|
||||
template <class T, class BC, size_t thr, class CMP>
|
||||
class quad_tree_node
|
||||
{
|
||||
public:
|
||||
|
|
@ -137,7 +137,7 @@ public:
|
|||
if (! m_split || n < 0) {
|
||||
|
||||
for (auto i = m_objects.begin (); i != m_objects.end (); ++i) {
|
||||
if (*i == value) {
|
||||
if (CMP () (*i, value)) {
|
||||
m_objects.erase (i);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -290,7 +290,7 @@ private:
|
|||
}
|
||||
|
||||
box_type b = BC () (value);
|
||||
if (b.inside (box (ucenter))) {
|
||||
if (inside (b, box (ucenter))) {
|
||||
|
||||
int n = quad_for (b);
|
||||
if (n < 0) {
|
||||
|
|
@ -337,7 +337,7 @@ private:
|
|||
|
||||
coord_type dx = std::max (std::abs (total_box.left () - m_center.x ()), std::abs (total_box.right () - 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 * 2, dy * 2);
|
||||
}
|
||||
|
||||
bool check (const point_type &ucenter) const
|
||||
|
|
@ -348,10 +348,15 @@ private:
|
|||
|
||||
for (auto i = m_objects.begin (); i != m_objects.end (); ++i) {
|
||||
box_type b = BC () (*i);
|
||||
if (! b.inside (bq)) {
|
||||
if (! inside (b, bq)) {
|
||||
tl::error << "Box " << b.to_string () << " not inside quad box " << bq.to_string ();
|
||||
result = false;
|
||||
}
|
||||
if (coord_traits::equal (b.left (), ucenter.x ()) || coord_traits::equal (b.right (), ucenter.x ()) ||
|
||||
coord_traits::equal (b.bottom (), ucenter.y ()) || coord_traits::equal (b.top (), ucenter.y ())) {
|
||||
tl::error << "Box " << b.to_string () << " touches center of upper-level quad " << ucenter.to_string ();
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_split) {
|
||||
|
|
@ -367,9 +372,11 @@ private:
|
|||
|
||||
for (unsigned int n = 0; n < 4; ++n) {
|
||||
if (m_q[n]) {
|
||||
m_q[n]->check (m_center);
|
||||
if (! m_q[n]->check (m_center)) {
|
||||
result = false;
|
||||
}
|
||||
box_type bbq = m_q[n]->box (m_center);
|
||||
if (bbq != q (n, ucenter)) {
|
||||
if (! bbq.equal (q (n, ucenter))) {
|
||||
tl::error << "Quad not centered (quad box is " << bbq.to_string () << ", should be " << q (n, ucenter).to_string ();
|
||||
result = false;
|
||||
}
|
||||
|
|
@ -394,13 +401,23 @@ private:
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool inside (const box_type &box, const box_type &in)
|
||||
{
|
||||
if (box.empty () || in.empty ()) {
|
||||
return false;
|
||||
} else {
|
||||
return ! coord_traits::less (box.left (), in.left ()) && ! coord_traits::less (in.right (), box.right ()) &&
|
||||
! coord_traits::less (box.bottom (), in.bottom ()) && ! coord_traits::less (in.top (), box.top ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class BC, size_t thr, class S>
|
||||
template <class T, class BC, size_t thr, class CMP, class S>
|
||||
class quad_tree_iterator
|
||||
{
|
||||
public:
|
||||
typedef quad_tree_node<T, BC, thr> quad_tree_node_type;
|
||||
typedef quad_tree_node<T, BC, thr, CMP> quad_tree_node_type;
|
||||
typedef typename T::coord_type coord_type;
|
||||
typedef db::box<coord_type> box_type;
|
||||
|
||||
|
|
@ -575,15 +592,23 @@ private:
|
|||
box_type m_box;
|
||||
};
|
||||
|
||||
// @@@ TODO: copy, assignment, move, swap
|
||||
template <class T, class BC, size_t thr>
|
||||
template <class T>
|
||||
struct quad_tree_default_cmp
|
||||
{
|
||||
bool operator() (const T &a, const T &b) const
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class BC, size_t thr, class CMP = quad_tree_default_cmp<T>>
|
||||
class quad_tree
|
||||
{
|
||||
public:
|
||||
typedef quad_tree_node<T, BC, thr> quad_tree_node_type;
|
||||
typedef quad_tree_iterator<T, BC, thr, quad_tree_always_sel<T, BC> > quad_tree_flat_iterator;
|
||||
typedef quad_tree_iterator<T, BC, thr, quad_tree_touching_sel<T, BC> > quad_tree_touching_iterator;
|
||||
typedef quad_tree_iterator<T, BC, thr, quad_tree_overlapping_sel<T, BC> > quad_tree_overlapping_iterator;
|
||||
typedef quad_tree_node<T, BC, thr, CMP> quad_tree_node_type;
|
||||
typedef quad_tree_iterator<T, BC, thr, CMP, quad_tree_always_sel<T, BC> > quad_tree_flat_iterator;
|
||||
typedef quad_tree_iterator<T, BC, thr, CMP, quad_tree_touching_sel<T, BC> > quad_tree_touching_iterator;
|
||||
typedef quad_tree_iterator<T, BC, thr, CMP, quad_tree_overlapping_sel<T, BC> > quad_tree_overlapping_iterator;
|
||||
typedef typename T::coord_type coord_type;
|
||||
typedef db::box<coord_type> box_type;
|
||||
typedef db::point<coord_type> point_type;
|
||||
|
|
|
|||
|
|
@ -28,9 +28,17 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef db::quad_tree<db::DBox, db::box_convert<db::DBox>, size_t (1)> my_quad_tree;
|
||||
struct MyQuadTreeCMP
|
||||
{
|
||||
bool operator() (const db::DBox &a, const db::DBox &b) const
|
||||
{
|
||||
return a.equal (b);
|
||||
}
|
||||
};
|
||||
|
||||
std::string find_all (const my_quad_tree &qt)
|
||||
typedef db::quad_tree<db::DBox, db::box_convert<db::DBox>, size_t (1), MyQuadTreeCMP> MyQuadTree;
|
||||
|
||||
std::string find_all (const MyQuadTree &qt)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
auto i = qt.begin ();
|
||||
|
|
@ -42,7 +50,7 @@ std::string find_all (const my_quad_tree &qt)
|
|||
return tl::join (v, "/");
|
||||
}
|
||||
|
||||
std::string find_touching (const my_quad_tree &qt, const db::DBox &box)
|
||||
std::string find_touching (const MyQuadTree &qt, const db::DBox &box)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
auto i = qt.begin_touching (box);
|
||||
|
|
@ -54,7 +62,7 @@ std::string find_touching (const my_quad_tree &qt, const db::DBox &box)
|
|||
return tl::join (v, "/");
|
||||
}
|
||||
|
||||
std::string find_touching_from_all (const my_quad_tree &qt, const db::DBox &box)
|
||||
std::string find_touching_from_all (const MyQuadTree &qt, const db::DBox &box)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
auto i = qt.begin ();
|
||||
|
|
@ -68,7 +76,7 @@ std::string find_touching_from_all (const my_quad_tree &qt, const db::DBox &box)
|
|||
return tl::join (v, "/");
|
||||
}
|
||||
|
||||
std::string find_overlapping (const my_quad_tree &qt, const db::DBox &box)
|
||||
std::string find_overlapping (const MyQuadTree &qt, const db::DBox &box)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
auto i = qt.begin_overlapping (box);
|
||||
|
|
@ -80,7 +88,7 @@ std::string find_overlapping (const my_quad_tree &qt, const db::DBox &box)
|
|||
return tl::join (v, "/");
|
||||
}
|
||||
|
||||
std::string find_overlapping_from_all (const my_quad_tree &qt, const db::DBox &box)
|
||||
std::string find_overlapping_from_all (const MyQuadTree &qt, const db::DBox &box)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
auto i = qt.begin ();
|
||||
|
|
@ -96,7 +104,7 @@ std::string find_overlapping_from_all (const my_quad_tree &qt, const db::DBox &b
|
|||
|
||||
TEST(basic)
|
||||
{
|
||||
my_quad_tree tree;
|
||||
MyQuadTree tree;
|
||||
EXPECT_EQ (tree.empty (), true);
|
||||
EXPECT_EQ (tree.size (), size_t (0));
|
||||
EXPECT_EQ (tree.check (), true);
|
||||
|
|
@ -174,7 +182,7 @@ TEST(basic)
|
|||
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 (tree.levels (), size_t (3));
|
||||
|
||||
EXPECT_EQ (find_all (tree), "(-1,-2;3,4)/(-1,-3;-0.5,-2)/(-1,-3;3,0)");
|
||||
|
||||
|
|
@ -204,7 +212,7 @@ TEST(basic)
|
|||
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 (tree.levels (), size_t (3));
|
||||
|
||||
EXPECT_EQ (find_all (tree), "(-1,-2;3,4)/(-1,-3;-0.5,-2)/(-1,-3;-0.5,2)/(-1,-3;3,0)");
|
||||
|
||||
|
|
@ -233,7 +241,7 @@ TEST(basic)
|
|||
|
||||
TEST(remove)
|
||||
{
|
||||
my_quad_tree tree;
|
||||
MyQuadTree 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));
|
||||
|
|
@ -260,12 +268,12 @@ TEST(remove)
|
|||
|
||||
TEST(grow)
|
||||
{
|
||||
my_quad_tree tree;
|
||||
MyQuadTree 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));
|
||||
EXPECT_EQ (tree.levels (), size_t (3));
|
||||
tree.insert (db::DBox (-100, -3, -99, 2));
|
||||
EXPECT_EQ (tree.levels (), size_t (8));
|
||||
|
||||
|
|
@ -286,12 +294,12 @@ TEST(grow)
|
|||
|
||||
TEST(grow2)
|
||||
{
|
||||
my_quad_tree tree;
|
||||
MyQuadTree 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));
|
||||
EXPECT_EQ (tree.levels (), size_t (3));
|
||||
tree.insert (db::DBox (-100, -3, -99, -1));
|
||||
EXPECT_EQ (tree.levels (), size_t (8));
|
||||
|
||||
|
|
@ -312,7 +320,7 @@ TEST(grow2)
|
|||
|
||||
TEST(clear)
|
||||
{
|
||||
my_quad_tree tree;
|
||||
MyQuadTree 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));
|
||||
|
|
@ -332,7 +340,7 @@ TEST(clear)
|
|||
|
||||
TEST(copy)
|
||||
{
|
||||
my_quad_tree tree;
|
||||
MyQuadTree 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));
|
||||
|
|
@ -340,19 +348,19 @@ TEST(copy)
|
|||
|
||||
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));
|
||||
EXPECT_EQ (tree.levels (), size_t (3));
|
||||
|
||||
my_quad_tree tree2 (tree);
|
||||
MyQuadTree 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));
|
||||
EXPECT_EQ (tree2.levels (), size_t (3));
|
||||
}
|
||||
|
||||
TEST(assign)
|
||||
{
|
||||
my_quad_tree tree;
|
||||
MyQuadTree 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));
|
||||
|
|
@ -360,20 +368,20 @@ TEST(assign)
|
|||
|
||||
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));
|
||||
EXPECT_EQ (tree.levels (), size_t (3));
|
||||
|
||||
my_quad_tree tree2;
|
||||
MyQuadTree 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));
|
||||
EXPECT_EQ (tree2.levels (), size_t (3));
|
||||
}
|
||||
|
||||
TEST(swap)
|
||||
{
|
||||
my_quad_tree tree;
|
||||
MyQuadTree 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));
|
||||
|
|
@ -381,9 +389,9 @@ TEST(swap)
|
|||
|
||||
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));
|
||||
EXPECT_EQ (tree.levels (), size_t (3));
|
||||
|
||||
my_quad_tree tree2;
|
||||
MyQuadTree tree2;
|
||||
tree2.swap (tree);
|
||||
|
||||
EXPECT_EQ (tree.check (), true);
|
||||
|
|
@ -393,12 +401,12 @@ TEST(swap)
|
|||
|
||||
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));
|
||||
EXPECT_EQ (tree2.levels (), size_t (3));
|
||||
}
|
||||
|
||||
TEST(move)
|
||||
{
|
||||
my_quad_tree tree;
|
||||
MyQuadTree 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));
|
||||
|
|
@ -406,9 +414,9 @@ TEST(move)
|
|||
|
||||
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));
|
||||
EXPECT_EQ (tree.levels (), size_t (3));
|
||||
|
||||
my_quad_tree tree2;
|
||||
MyQuadTree tree2;
|
||||
tree2 = std::move (tree);
|
||||
|
||||
EXPECT_EQ (tree.check (), true);
|
||||
|
|
@ -418,12 +426,12 @@ TEST(move)
|
|||
|
||||
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));
|
||||
EXPECT_EQ (tree2.levels (), size_t (3));
|
||||
}
|
||||
|
||||
TEST(move_ctor)
|
||||
{
|
||||
my_quad_tree tree;
|
||||
MyQuadTree 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));
|
||||
|
|
@ -431,9 +439,9 @@ TEST(move_ctor)
|
|||
|
||||
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));
|
||||
EXPECT_EQ (tree.levels (), size_t (3));
|
||||
|
||||
my_quad_tree tree2 (std::move (tree));
|
||||
MyQuadTree tree2 (std::move (tree));
|
||||
|
||||
EXPECT_EQ (tree.check (), true);
|
||||
EXPECT_EQ (tree.empty (), true);
|
||||
|
|
@ -442,7 +450,7 @@ TEST(move_ctor)
|
|||
|
||||
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));
|
||||
EXPECT_EQ (tree2.levels (), size_t (3));
|
||||
}
|
||||
|
||||
static double rvalue ()
|
||||
|
|
@ -452,13 +460,16 @@ static double rvalue ()
|
|||
|
||||
static db::DBox rbox ()
|
||||
{
|
||||
return db::DBox (db::DPoint (rvalue (), rvalue ()), db::DPoint (rvalue (), rvalue ()));
|
||||
db::DBox box;
|
||||
while ((box = db::DBox (db::DPoint (rvalue (), rvalue ()), db::DPoint (rvalue (), rvalue ()))).empty ()) {
|
||||
;
|
||||
}
|
||||
return box;
|
||||
}
|
||||
|
||||
TEST(many)
|
||||
{
|
||||
return; // @@@
|
||||
my_quad_tree tree;
|
||||
MyQuadTree tree;
|
||||
|
||||
unsigned int n = 1000;
|
||||
|
||||
|
|
@ -467,6 +478,7 @@ TEST(many)
|
|||
}
|
||||
|
||||
EXPECT_EQ (tree.check (), true);
|
||||
EXPECT_EQ (tree.size (), size_t (n));
|
||||
|
||||
bool r = true;
|
||||
while (r && ! tree.empty ()) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue