18 virtual const vec2_type& get_point(
int i)
const = 0;
25 node() : is_leaf(
true) { children[0] = children[1] = children[2] = children[3] = -1; }
27 unsigned size()
const {
unsigned s = 0;
while (s < 4 && children[s] != -1) ++s;
return s; }
30 const point_provider& provider;
32 std::vector<node> nodes;
34 const node& get_node(
int ni)
const {
return nodes[ni]; }
35 node& ref_node(
int ni) {
return nodes[ni]; }
37 bool is_leaf(
int ni)
const {
return nodes[ni].is_leaf; }
38 void add_point_to_leaf(
int pi,
int ni) {
39 node& n = ref_node(ni);
40 assert(n.is_leaf && n.size() < 4);
41 n.children[n.size()] = pi;
43 bool split_leaf(
int ni,
const vec2_type& x) {
46 int c0 = (int)nodes.size();
47 nodes.resize(nodes.size() + 4);
48 node& n = ref_node(ni);
49 for (
unsigned j = 0; j < 4; ++j) {
50 int pi = n.children[j];
52 const vec2_type& p = provider.get_point(pi);
58 add_point_to_leaf(pi, c0 + k);
60 n.children[j] = c0 + j;
66 quadtree(
const point_provider& _provider,
const box2_type& _box) : provider(_provider), box(_box) { nodes.push_back(node()); root_idx = 0; }
67 bool empty()
const {
return is_leaf(get_root_index()) && get_node(get_root_index()).
size() == 0; }
68 int get_root_index()
const {
return root_idx; }
69 bool collides(
const vec2_type& x, T d,
int ni = -1, box2_type b = box2_type())
const {
71 ni = get_root_index();
75 if (x(0) + d > b.get_min_pnt()(0) && x(0) - d < b.get_max_pnt()(0) &&
76 x(1) + d > b.get_min_pnt()(1) && x(1) - d < b.get_max_pnt()(1)) {
79 const node& n = get_node(ni);
80 for (
unsigned j = 0; j < 4; ++j) {
81 if (n.children[j] == -1)
83 if ((provider.get_point(n.children[j])-x).length() < d)
89 vec2_type c = b.get_center();
90 const node& n = get_node(ni);
92 collides(x, d, n.children[0], box2_type(b.get_min_pnt(), c)) ||
93 collides(x, d, n.children[1], box2_type(vec2_type(c(0), b.get_min_pnt()(1)), vec2_type(b.get_max_pnt()(0), c(1)))) ||
94 collides(x, d, n.children[2], box2_type(vec2_type(b.get_min_pnt()(0), c(1)), vec2_type(c(0), b.get_max_pnt()(1)))) ||
95 collides(x, d, n.children[3], box2_type(c, b.get_max_pnt()));
101 void insert(
const vec2_type& p,
int pi) {
102 int ni = get_root_index();
106 const node& n = get_node(ni);
108 add_point_to_leaf(pi, ni);
111 split_leaf(ni, b.get_center());
113 vec2_type x = b.get_center();
117 b.ref_min_pnt()(0) = x(0);
120 b.ref_max_pnt()(0) = x(0);
124 b.ref_min_pnt()(1) = x(1);
127 b.ref_max_pnt()(1) = x(1);
129 ni = get_node(ni).children[k];