1 #ifndef UGDK_UTIL_INTERVALKDTREE_H_
2 #define UGDK_UTIL_INTERVALKDTREE_H_
18 template <
int DIMENSIONS>
21 template <
class T,
int DIMENSIONS>
24 template <
class T,
int DIMENSIONS>
29 template <
class T,
int DIMENSIONS>
42 unsigned int max_height_;
46 unsigned int max_elements_per_leaf_;
48 std::map<T,Item<T, DIMENSIONS>* > container_items_;
53 template <
int DIMENSIONS>
73 template <
class T,
int DIMENSIONS>
90 template <
class T,
int DIMENSIONS>
101 std::vector<T> *items)
const;
107 void PrintTreeRootedAtThisNode ();
113 Node * low_child_, * high_child_;
119 std::list<Item<T, DIMENSIONS> *> items_;
127 template <
class T,
int DIMENSIONS>
130 unsigned int max_elements_per_leaf) :
131 max_elements_per_leaf_(max_elements_per_leaf),
132 tree_bounding_box_(tree_bounding_box),
140 template <
class T,
int DIMENSIONS>
146 template <
class T,
int DIMENSIONS>
148 container_items_.clear ();
154 template <
class T,
int DIMENSIONS>
157 assert (!container_items_.count (element));
159 root_->InsertItem (item);
160 container_items_[element] = item;
163 template <
class T,
int DIMENSIONS>
165 assert (container_items_.count (element));
166 if (container_items_.count (element)) {
170 container_items_.erase (element);
175 template <
class T,
int DIMENSIONS>
179 assert (container_items_.count(element));
181 item->
setBox (new_bounding_box);
185 template <
class T,
int DIMENSIONS>
194 ) || !container_node->
Contains (*item)) {
198 root_->InsertItem (item);
202 template <
class T,
int DIMENSIONS>
205 std::vector<T>* items =
new std::vector<T>;
206 root_->getIntersectingItems (boundary, items);
210 template <
class T,
int DIMENSIONS>
212 return max_elements_per_leaf_;
216 template <
class T,
int DIMENSIONS>
218 root_->PrintTreeRootedAtThisNode ();
224 template <
int DIMENSIONS>
226 if (min_coordinates != NULL && max_coordinates != NULL) {
227 for (
int k = 0; k < DIMENSIONS; ++k) {
228 min_coordinates_[k] = min_coordinates[k];
229 max_coordinates_[k] = max_coordinates[k];
234 template <
int DIMENSIONS>
236 for (
int k = 0; k < DIMENSIONS; ++k) {
242 template <
int DIMENSIONS>
245 template <
int DIMENSIONS>
247 for (
int k = 0; k < DIMENSIONS; ++k) {
253 template <
int DIMENSIONS>
255 return max_coordinates_[depth % DIMENSIONS] <= boundary;
258 template <
int DIMENSIONS>
260 return boundary < min_coordinates_[depth % DIMENSIONS];
263 template <
int DIMENSIONS>
265 for (
int k = 0; k < DIMENSIONS; ++k) {
276 template <
int DIMENSIONS>
278 for (
int k = 0; k < DIMENSIONS; ++k) {
289 template <
class T,
int DIMENSIONS>
291 super (bounding_box), element_(element) {}
293 template <
class T,
int DIMENSIONS>
296 template <
class T,
int DIMENSIONS>
298 return container_node_;
301 template <
class T,
int DIMENSIONS>
303 container_node_ = container_node;
306 template <
class T,
int DIMENSIONS>
312 template <
class T,
int DIMENSIONS>
314 std::cout << element_;
320 template <
class T,
int DIMENSIONS>
322 Node *parent,
int depth,
324 super (min_coordinates, max_coordinates), depth_(depth), has_children_(false),
325 tree_(tree), parent_(parent), low_child_(NULL), high_child_(NULL) {}
327 template <
class T,
int DIMENSIONS>
330 super (coordinates), depth_(depth), has_children_(false),
331 tree_(tree), parent_(parent), low_child_(NULL), high_child_(NULL) {}
333 template <
class T,
int DIMENSIONS>
341 template <
class T,
int DIMENSIONS>
344 if (static_cast<unsigned int>(depth_) > tree_->max_height_) {
345 tree_->max_height_ = depth_;
349 if (item->
IsBelow (depth_, division_boundary_)) {
351 low_child_->InsertItem (item);
353 }
else if (item->
IsAbove (depth_, division_boundary_)) {
354 assert (high_child_);
355 high_child_->InsertItem (item);
359 items_.push_back (item);
361 if (!has_children_ && items_.size() > tree_->max_elements_per_leaf()) {
366 template <
class T,
int DIMENSIONS>
368 items_.remove (item);
373 template <
class T,
int DIMENSIONS>
375 std::vector<T> *intersecting_items)
const {
377 it != items_.end(); ++it) {
379 intersecting_items->push_back ((*it)->element ());
383 if (boundary.
IsBelow (depth_, division_boundary_)) {
384 low_child_->getIntersectingItems (boundary, intersecting_items);
385 }
else if (boundary.
IsAbove (depth_, division_boundary_)) {
386 high_child_->getIntersectingItems (boundary, intersecting_items);
388 low_child_->getIntersectingItems (boundary, intersecting_items);
389 high_child_->getIntersectingItems (boundary, intersecting_items);
394 template <
class T,
int DIMENSIONS>
396 assert (!has_children_);
397 has_children_ =
true;
399 int dimension = depth_ % DIMENSIONS;
401 division_boundary_ = ( this->min_coordinates_[dimension]
402 + this->max_coordinates_[dimension]) / 2;
405 new_max_coordinates[DIMENSIONS];
406 for (
int k = 0; k < DIMENSIONS; ++k) {
407 if (k == dimension) {
408 new_min_coordinates[k] = new_max_coordinates[k]
409 = division_boundary_;
411 new_min_coordinates[k] = this->min_coordinates_[k];
412 new_max_coordinates[k] = this->max_coordinates_[k];
415 low_child_ =
new Node (tree_,
this, depth_ + 1,
416 this->min_coordinates_, new_max_coordinates);
417 high_child_ =
new Node (tree_,
this, depth_ + 1,
418 new_min_coordinates, this->max_coordinates_);
420 std::list<Item<T, DIMENSIONS> *> old_items_list = items_;
423 = old_items_list.begin(); it != old_items_list.end(); ++it) {
428 template <
class T,
int DIMENSIONS>
430 assert (has_children_);
431 if ( !low_child_->has_children_
432 && !high_child_->has_children_
434 + low_child_->items_.size ()
435 + high_child_->items_.size ()
436 < tree_->max_elements_per_leaf () )) {
438 = low_child_->items_.begin(); it != low_child_->items_.end();
440 items_.push_back (*it);
441 (*it)->set_container_node (
this);
444 = high_child_->items_.begin(); it != high_child_->items_.end();
446 items_.push_back (*it);
447 (*it)->set_container_node (
this);
453 has_children_ =
false;
459 template <
class T,
int DIMENSIONS>
462 low_child_->Clear ();
463 high_child_->Clear ();
470 = items_.begin(); it != items_.end(); ++it) {
476 template <
class T,
int DIMENSIONS>
479 high_child_->PrintTreeRootedAtThisNode ();
481 for (
int i = 0; i < depth_; ++i) {
486 = items_.begin(); it != items_.end(); ++it, ++i) {
487 std::cout <<
"[" << i <<
"] = ";
491 std::cout << std::endl;
493 low_child_->PrintTreeRootedAtThisNode ();