1 #ifndef UGDK_UTIL_INTERVALKDTREE_H_
2 #define UGDK_UTIL_INTERVALKDTREE_H_
20 template <
class T,
int DIMENSIONS>
29 void Remove(
const T& element);
32 template<
class OutputIterator>
35 typename std::map<T, Item<T, DIMENSIONS>* >::const_iterator
begin()
const;
36 typename std::map<T, Item<T, DIMENSIONS>* >::const_iterator
end()
const;
41 unsigned int max_height_;
42 void PrintTree()
const;
48 unsigned int max_elements_per_leaf_;
50 std::map<T, Item<T, DIMENSIONS>* > container_items_;
58 template <
class T,
int DIMENSIONS>
79 template <
class T,
int DIMENSIONS>
92 template<
typename Iterator>
102 void PrintTreeRootedAtThisNode();
112 Node * low_child_, * high_child_;
119 std::list<Item<T, DIMENSIONS> *> items_;
124 template <
class T,
int DIMENSIONS>
127 unsigned int _max_elements_per_leaf) :
128 max_elements_per_leaf_(_max_elements_per_leaf),
129 tree_bounding_box_(_tree_bounding_box),
137 template <
class T,
int DIMENSIONS>
143 template <
class T,
int DIMENSIONS>
145 container_items_.clear ();
151 template <
class T,
int DIMENSIONS>
154 assert (!container_items_.count (element));
156 root_->InsertItem (item);
157 container_items_[element] = item;
160 template <
class T,
int DIMENSIONS>
162 assert (container_items_.count (element));
163 if (container_items_.count (element)) {
167 container_items_.erase (element);
172 template <
class T,
int DIMENSIONS>
176 assert (container_items_.count(element));
182 template <
class T,
int DIMENSIONS>
191 ) || !container_node->
Contains (*item)) {
195 root_->InsertItem (item);
199 template <
class T,
int DIMENSIONS>
200 template <
class OutputIterator>
202 root_->FindIntersectingItems(boundary, output);
205 template <
class T,
int DIMENSIONS>
207 return container_items_.begin();
210 template <
class T,
int DIMENSIONS>
212 return container_items_.end();
215 template <
class T,
int DIMENSIONS>
217 return max_elements_per_leaf_;
221 template <
class T,
int DIMENSIONS>
223 root_->PrintTreeRootedAtThisNode ();
229 template <
class T,
int DIMENSIONS>
231 super(bounding_box), element_(_element) {}
233 template <
class T,
int DIMENSIONS>
236 template <
class T,
int DIMENSIONS>
238 return container_node_;
241 template <
class T,
int DIMENSIONS>
243 container_node_ = _container_node;
246 template <
class T,
int DIMENSIONS>
252 template <
class T,
int DIMENSIONS>
254 std::cout << element_;
260 template <
class T,
int DIMENSIONS>
262 const std::array<Coordinate, DIMENSIONS>& min_coordinates,
263 const std::array<Coordinate, DIMENSIONS>& max_coordinates)
265 :
super (min_coordinates, max_coordinates), depth_(depth), has_children_(false),
266 tree_(tree), parent_(parent), low_child_(nullptr), high_child_(nullptr) {}
268 template <
class T,
int DIMENSIONS>
272 :
super (coordinates), depth_(depth), has_children_(false),
273 tree_(tree), parent_(parent), low_child_(nullptr), high_child_(nullptr) {}
275 template <
class T,
int DIMENSIONS>
281 template <
class T,
int DIMENSIONS>
284 if (static_cast<unsigned int>(depth_) > tree_->max_height_) {
285 tree_->max_height_ = depth_;
289 if (item->
IsBelow (depth_, division_boundary_)) {
291 low_child_->InsertItem (item);
293 }
else if (item->
IsAbove (depth_, division_boundary_)) {
294 assert (high_child_);
295 high_child_->InsertItem (item);
299 items_.push_back (item);
301 if (!has_children_ && items_.size() > tree_->max_elements_per_leaf()) {
306 template <
class T,
int DIMENSIONS>
308 items_.remove (item);
313 template <
class T,
int DIMENSIONS>
314 template <
class Iterator>
318 *output++ = it->element();
320 if (boundary.
IsBelow(depth_, division_boundary_)) {
321 low_child_->FindIntersectingItems(boundary, output);
322 }
else if (boundary.
IsAbove(depth_, division_boundary_)) {
323 high_child_->FindIntersectingItems(boundary, output);
325 low_child_->FindIntersectingItems(boundary, output);
326 high_child_->FindIntersectingItems(boundary, output);
331 template <
class T,
int DIMENSIONS>
333 assert (!has_children_);
334 has_children_ =
true;
336 int dimension = depth_ % DIMENSIONS;
338 division_boundary_ = ( this->min_coordinates_[dimension]
339 + this->max_coordinates_[dimension]) / 2;
341 std::array<Coordinate, DIMENSIONS> new_min_coordinates,
343 for (
int k = 0; k < DIMENSIONS; ++k) {
344 if (k == dimension) {
345 new_min_coordinates[k] = new_max_coordinates[k]
346 = division_boundary_;
348 new_min_coordinates[k] = this->min_coordinates_[k];
349 new_max_coordinates[k] = this->max_coordinates_[k];
352 low_child_ =
new Node(tree_,
this, depth_ + 1, this->min_coordinates_, new_max_coordinates);
353 high_child_ =
new Node(tree_,
this, depth_ + 1, new_min_coordinates, this->max_coordinates_);
355 std::list<Item<T, DIMENSIONS> *> old_items_list = items_;
357 for (Item<T, DIMENSIONS>* it : old_items_list)
361 template <
class T,
int DIMENSIONS>
362 void Node<T, DIMENSIONS>::Merge () {
363 assert (has_children_);
364 if ( !low_child_->has_children_
365 && !high_child_->has_children_
367 + low_child_->items_.size ()
368 + high_child_->items_.size ()
369 < tree_->max_elements_per_leaf () )) {
370 for (Item<T, DIMENSIONS>* it : low_child_->items_) {
371 items_.push_back(it);
372 it->set_container_node(
this);
374 for (Item<T, DIMENSIONS>* it : high_child_->items_) {
375 items_.push_back(it);
376 it->set_container_node(
this);
379 low_child_ =
nullptr;
381 high_child_ =
nullptr;
382 has_children_ =
false;
388 template <
class T,
int DIMENSIONS>
391 low_child_->Clear ();
392 high_child_->Clear ();
394 low_child_ =
nullptr;
396 high_child_ =
nullptr;
404 template <
class T,
int DIMENSIONS>
407 high_child_->PrintTreeRootedAtThisNode ();
409 for (
int i = 0; i < depth_; ++i) {
413 for (
auto it = items_.begin(); it != items_.end(); ++it, ++i) {
414 std::cout <<
"[" << i <<
"] = ";
418 std::cout << std::endl;
420 low_child_->PrintTreeRootedAtThisNode ();
const Point & min_coordinates() const
Definition: box.h:85
const T & element() const
Definition: intervalkdtree.h:247
~Node()
Definition: intervalkdtree.h:276
void set_container_node(Node< T, DIMENSIONS > *container_node)
Definition: intervalkdtree.h:242
bool IsAbove(int depth, Coordinate boundary) const
Definition: box.h:56
void RemoveItem(Item< T, DIMENSIONS > *item)
Definition: intervalkdtree.h:307
unsigned int max_elements_per_leaf() const
Definition: intervalkdtree.h:216
Definition: intervalkdtree.h:80
void Remove(const T &element)
Definition: intervalkdtree.h:161
bool Intersects(const Box *box) const
Definition: box.h:74
Definition: animation.h:11
Definition: intervalkdtree.h:21
void FindIntersectingItems(const Box< DIMENSIONS > &boundary, Iterator it) const
Definition: intervalkdtree.h:315
Node< T, DIMENSIONS > * container_node() const
Definition: intervalkdtree.h:237
void UpdateBox(const Box &)
Definition: box.h:46
const Point & max_coordinates() const
Definition: box.h:90
void FindIntersectingItems(const Box< DIMENSIONS > &boundary, OutputIterator output) const
Definition: intervalkdtree.h:201
~Item()
Definition: intervalkdtree.h:234
std::map< T, Item< T, DIMENSIONS > * >::const_iterator begin() const
Definition: intervalkdtree.h:206
~IntervalKDTree()
Definition: intervalkdtree.h:138
void Update(const Box< DIMENSIONS > &new_bounding_box, const T &element)
Definition: intervalkdtree.h:173
bool IsBelow(int depth, Coordinate boundary) const
Definition: box.h:51
Definition: intervalkdtree.h:59
int depth_
Definition: intervalkdtree.h:97
void Insert(const Box< DIMENSIONS > &bounding_box, const T &element)
Definition: intervalkdtree.h:152
std::map< T, Item< T, DIMENSIONS > * >::const_iterator end() const
Definition: intervalkdtree.h:211
IntervalKDTree(const Box< DIMENSIONS > &tree_bounding_box, unsigned int max_elements_per_leaf)
Definition: intervalkdtree.h:125
Item(const Box< DIMENSIONS > &bounding_box, const T &element)
Definition: intervalkdtree.h:230
Coordinate division_boundary_
Definition: intervalkdtree.h:98
void Clear()
Definition: intervalkdtree.h:144
void InsertItem(Item< T, DIMENSIONS > *item)
Definition: intervalkdtree.h:282
void Clear()
Definition: intervalkdtree.h:389
bool Contains(const Box &box) const
Definition: box.h:61
double Coordinate
Definition: structure.h:7
Node(IntervalKDTree< T, DIMENSIONS > *tree, Node *parent, int depth, const std::array< Coordinate, DIMENSIONS > &min_coordinates, const std::array< Coordinate, DIMENSIONS > &max_coordinates)
Definition: intervalkdtree.h:261
bool has_children_
Definition: intervalkdtree.h:99