24#define _RTREE_PRINT(x) ;
25#define _RTREE_PRINT_TREE( x, y ) ;
26#define _RTREE_PRINT_TREE_INS( x, y, z ) ;
70 _RTREE_PRINT(
"\n=====================================");
71 _RTREE_PRINT(
"insert");
79 const bool &insert_high ,
80 const unsigned &stop_height ,
84 _RTREE_PRINT(
"\n--------------");
85 _RTREE_PRINT(
"insert private. element:" << leaf_record.
data <<
" insert high:" << insert_high <<
" stop height:" << stop_height );
94 if( insert_high ==
false ){
100 _RTREE_PRINT(
"leaf node chosen: " );
101 _RTREE_PRINT_TREE( position , 0 );
102 std::pair< RTreeNode*, RTreeNode* > node_division;
104 bool split_performed =
false;
108 assert( insert_high ==
true );
113 _RTREE_PRINT(
"I2 nonleaf: no split: " << position->
children_nodes.size() );
116 _RTREE_PRINT(
"I2 nonleaf: split: " << position->
children_nodes.size() );
118 split_performed =
true;
124 assert( insert_high ==
false );
130 _RTREE_PRINT(
"I2 leaf: no split: " << position->
children_leaves.size() );
135 split_performed =
true;
137 _RTREE_PRINT(
" group A");
138 _RTREE_PRINT_TREE( node_division.first , 3 );
139 _RTREE_PRINT(
" group B");
140 _RTREE_PRINT_TREE( node_division.second , 3 );
147 bool root_split_performed =
adjust_tree( position, node_division, split_performed );
148 _RTREE_PRINT(
"root split: " << root_split_performed);
155 if( root_split_performed ){
156 std::pair<RTreeNode*, RTreeNode*> root_division;
159 Rect first_record_bounding_box;
160 Rect second_record_bounding_box;
164 _RTREE_PRINT(
" 1st:");
165 _RTREE_PRINT_TREE( first_new_record.
data, 5 );
166 _RTREE_PRINT(
" 2nd:");
167 _RTREE_PRINT_TREE( second_new_record.
data, 5 );
179 _RTREE_PRINT_TREE(
root, 5 );
182 _RTREE_PRINT(
"done");
189 delete node_division.first;
215 _RTREE_PRINT(
" CL1");
218 double min_enlargement;
219 double current_enlargement;
220 int node_min_enlargement;
221 unsigned current_height = 0;
223 _RTREE_PRINT(
" CL2 current_height:" << current_height <<
" stop_height:" << stop_height <<
" insert_high:" << insert_high);
226 && ( insert_high ? current_height < stop_height : true ) )
230 _RTREE_PRINT(
" CL3 current_height:" << current_height <<
" stop_height:" << stop_height );
231 min_enlargement = std::numeric_limits<double>::max();
232 current_enlargement = 0;
233 node_min_enlargement = 0;
239 if( current_enlargement < min_enlargement ){
240 node_min_enlargement = i;
241 min_enlargement = current_enlargement;
244 _RTREE_PRINT(
" CL4");
270 if( a_intersection_b.
empty() ){
271 _RTREE_PRINT(
" find_enlargement (no intersect): " << union_rect.
area() - a.
area() - b.
area() );
279 _RTREE_PRINT(
" find_enlargement (intersect: a cont b): " << a.
area() - b.
area() );
286 _RTREE_PRINT(
" find_enlargement (intersect: b cont a): " << a.
area() - b.
area() );
291 _RTREE_PRINT(
" find_enlargement (intersect: a partial cover b): " << union_rect.
area() - a.
area() - b.
area() - a_intersection_b->
area() );
292 return union_rect.
area()
293 - ( a.
area() - a_intersection_b->
area() )
294 - ( b.
area() - a_intersection_b->
area() );
336 _RTREE_PRINT(
" QS1");
337 std::pair<unsigned, unsigned> initial_seeds;
342 _RTREE_PRINT(
" non-leaf node");
345 std::fill( assigned_v.begin(), assigned_v.end(),
false );
348 assert(initial_seeds.first < assigned_v.size());
349 assigned_v[ initial_seeds.first ] =
true;
352 assert(initial_seeds.second < assigned_v.size());
353 assigned_v[ initial_seeds.second ] =
true;
355 _RTREE_PRINT(
" QS2");
359 while( num_of_not_assigned ){
360 _RTREE_PRINT(
" QS2 b, num_of_not_assigned:" << num_of_not_assigned);
369 for(
unsigned i = 0; i < assigned_v.size(); i++){
370 if(assigned_v[i] ==
false){
372 assigned_v[i] =
true;
380 for(
unsigned i = 0; i < assigned_v.size(); i++ ){
381 if( assigned_v[i] ==
false ){
383 assigned_v[i] =
true;
389 _RTREE_PRINT(
" QS3");
390 std::pair<unsigned, enum_add_to_group> next_element;
391 next_element =
pick_next( group_a, group_b, s, assigned_v );
399 num_of_not_assigned--;
404 _RTREE_PRINT(
" leaf node");
407 std::fill( assigned_v.begin(), assigned_v.end(),
false );
411 assert(initial_seeds.first < assigned_v.size());
412 assigned_v[ initial_seeds.first ] =
true;
416 assert(initial_seeds.second < assigned_v.size());
417 assigned_v[ initial_seeds.second ] =
true;
419 _RTREE_PRINT(
" QS2");
423 while( num_of_not_assigned ){
424 _RTREE_PRINT(
" QS2 b, num_of_not_assigned:" << num_of_not_assigned);
432 _RTREE_PRINT(
" add the non-assigned to group_a");
434 for(
unsigned i = 0; i < assigned_v.size(); i++ ){
435 if( assigned_v[i] ==
false ){
437 assigned_v[i] =
true;
444 _RTREE_PRINT(
" add the non-assigned to group_b");
446 for(
unsigned i = 0; i < assigned_v.size(); i++ ){
447 if( assigned_v[i] ==
false ){
449 assigned_v[i] =
true;
455 _RTREE_PRINT(
" QS3");
456 std::pair<unsigned, enum_add_to_group> next_element;
457 next_element =
pick_next(group_a, group_b, s, assigned_v);
465 num_of_not_assigned--;
468 assert( initial_seeds.first != initial_seeds.second );
469 return std::make_pair( group_a, group_b );
481 double current_d = 0;
482 double max_d = std::numeric_limits<double>::min();
485 _RTREE_PRINT(
" pick_seeds");
489 _RTREE_PRINT(
" non leaf");
490 _RTREE_PRINT(
" PS1");
495 _RTREE_PRINT(
" PS2 " << a <<
" - " << b );
498 if( current_d > max_d ){
508 _RTREE_PRINT(
" leaf node");
509 _RTREE_PRINT(
" PS1");
518 if( current_d > max_d ){
526 _RTREE_PRINT(
" seed_a: " << seed_a <<
" seed_b: " << seed_b );
527 return std::make_pair( seed_a, seed_b );
559 std::vector<bool> &assigned_v )
561 double max_increase_difference = std::numeric_limits<double>::min();
562 unsigned max_increase_difference_node = 0;
563 double current_increase_difference = 0;
574 double increase_area_a = 0;
575 double increase_area_b = 0;
577 _RTREE_PRINT(
" pick_next, assigned_v.size:" << assigned_v.size() );
581 _RTREE_PRINT(
" non leaf");
595 _RTREE_PRINT(
" PN1");
596 for(
unsigned i = 0; i < assigned_v.size(); i++ ){
597 _RTREE_PRINT(
" i:" << i <<
" assigned:" << assigned_v[i]);
598 if( assigned_v[i] ==
false ){
603 current_increase_difference = std::abs( increase_area_a - increase_area_b );
604 _RTREE_PRINT(
" PN2 " << i <<
": " << current_increase_difference );
605 if( current_increase_difference > max_increase_difference ){
606 max_increase_difference = current_increase_difference;
607 max_increase_difference_node = i;
610 if( increase_area_a < increase_area_b ){
620 assert(max_increase_difference_node < assigned_v.size());
621 assigned_v[max_increase_difference_node] =
true;
622 _RTREE_PRINT(
" ... i:" << max_increase_difference_node <<
" assigned:" << assigned_v[max_increase_difference_node] );
625 _RTREE_PRINT(
" leaf");
639 std::cout<<
"" << std::endl;
641 _RTREE_PRINT(
" PN1");
642 for(
unsigned i = 0; i < assigned_v.size(); i++ ){
643 _RTREE_PRINT(
" i:" << i <<
" assigned:" << assigned_v[i]);
644 if( assigned_v[i] ==
false ){
648 current_increase_difference = std::abs( increase_area_a - increase_area_b );
649 _RTREE_PRINT(
" PN2 " << i <<
": " << current_increase_difference );
651 if( current_increase_difference > max_increase_difference ){
652 max_increase_difference = current_increase_difference;
653 max_increase_difference_node = i;
656 if( increase_area_a < increase_area_b ){
665 assert(max_increase_difference_node < assigned_v.size());
666 assigned_v[max_increase_difference_node] =
true;
667 _RTREE_PRINT(
" ... i:" << max_increase_difference_node <<
" assigned:" << assigned_v[max_increase_difference_node] );
670 _RTREE_PRINT(
" node:" << max_increase_difference_node <<
" added:" << group_to_add );
671 return std::make_pair( max_increase_difference_node, group_to_add );
708 std::pair<RTreeNode*, RTreeNode*> &node_division,
709 bool initial_split_performed)
712 unsigned child_in_parent;
713 std::pair< RTreeNode*, bool > find_result;
714 bool split_performed = initial_split_performed;
715 bool root_split_performed =
false;
717 _RTREE_PRINT(
" adjust_tree");
718 _RTREE_PRINT(
" AT1");
721 _RTREE_PRINT(
" ------- current tree status:");
722 _RTREE_PRINT_TREE_INS(
root, 2,
true);
725 if( position ==
root ){
726 _RTREE_PRINT(
" AT2: found root");
727 if( split_performed ){
728 root_split_performed =
true;
733 if( split_performed ){
742 _RTREE_PRINT(
" AT3.1");
749 parent = find_result.first;
752 _RTREE_PRINT(
" AT3.2");
753 for( child_in_parent = 0; child_in_parent <
parent->children_nodes.size(); child_in_parent++ ){
754 if(
parent->children_nodes[ child_in_parent ].data == position){
755 _RTREE_PRINT(
" child_in_parent: " << child_in_parent);
760 _RTREE_PRINT(
" AT3.3");
765 _RTREE_PRINT(
" AT4");
766 if( split_performed ){
769 Rect new_record_bounding;
775 parent->children_nodes.push_back( new_record );
776 split_performed =
false;
779 parent->children_nodes.push_back( new_record );
781 split_performed =
true;
785 _RTREE_PRINT(
" AT5");
789 return root_split_performed;
808 _RTREE_PRINT(
"find_parent");
810 std::pair< RTreeNode*, bool >
result;
813 for(
unsigned i=0; i < subtree_root->
children_nodes.size(); i++ ){
815 _RTREE_PRINT(
"FOUND!!");
816 return std::make_pair( subtree_root,
true );
819 if( subtree_root->
children_nodes[i].bounding_box.intersects( search_area ) ){
834 _RTREE_PRINT(
" copy_group...(): install group A to existing non-leaf node");
842 _RTREE_PRINT(
" copy_group...(): install group A to existing leaf node");
883 for(
unsigned i=0; i < subtree_root->
children_nodes.size(); i++ ){
885 for(
int j=0; j < depth; j++){
890 _RTREE_PRINT_TREE_INS( subtree_root->
children_nodes[i].data, depth+1, used_during_insert);
895 for(
int j=0; j < depth; j++){
902 std::cout << children_leave.data <<
", " ;
904 std::cout << std::endl ;
915 sanity_check( children_node.data, depth+1, used_during_insert);
920 if( subtree_root !=
root ){
929 if( used_during_insert ){
940 if( subtree_root !=
root ){
949 if( used_during_insert ){
978 if( children_node.bounding_box.intersects( search_area ) ){
986 if( children_leave.bounding_box.intersects( search_area ) ){
987 result->push_back( children_leave.data );
1015 _RTREE_PRINT(
"\n=====================================");
1016 _RTREE_PRINT(
"erase element: " << shape_to_delete);
1018 _RTREE_PRINT(
"D1 & D2 : find and delete the leaf");
1020 if( !contains_record ){
1033 _RTREE_PRINT(
"D4 : non leaf: ");
1068 if( children_node.bounding_box.intersects( search_area ) ){
1079 if( it->data == shape_to_delete ){
1128 unsigned child_in_parent = 0;
1130 std::pair< RTreeNode*, bool > find_result;
1131 bool elimination_performed =
false;
1132 bool root_elimination_performed =
false;
1134 Rect special_case_bounding_box;
1135 _RTREE_PRINT(
" condense_tree");
1136 _RTREE_PRINT(
" CT1");
1138 std::vector< RTreeRecord_Leaf > Q_leaf_records( 0 );
1141 std::vector< std::pair< RTreeRecord_NonLeaf, unsigned > > Q_nonleaf_records( 0 );
1147 if( position ==
root ){
1148 _RTREE_PRINT(
" CT2 position is root");
1149 if( elimination_performed ){
1150 root_elimination_performed =
true;
1165 _RTREE_PRINT(
" CT2.1 - 2 non leaf: find parent, P is parent");
1171 && elimination_performed )
1173 _RTREE_PRINT(
" CT2.1 - 2 special case: find parent, P is parent");
1175 find_result =
find_parent(
root, special_case_bounding_box, position);
1178 _RTREE_PRINT(
" CT2.1 - 2 leaf: find parent, P is parent");
1183 parent = find_result.first;
1187 _RTREE_PRINT(
" CT2.3 find in parent, position's record EN");
1189 for( child_in_parent = 0; child_in_parent <
parent->children_nodes.size(); child_in_parent++ ){
1190 if(
parent->children_nodes[ child_in_parent ].data == position){
1191 _RTREE_PRINT(
" child_in_parent: " << child_in_parent <<
" out of " <<
parent->children_nodes.size() <<
" (size)" );
1197 _RTREE_PRINT(
" CT3 nonleaf: eliminate underfull node");
1200 _RTREE_PRINT(
" CT3.2 add N to Q");
1203 _RTREE_PRINT(
" i " << i );
1204 std::pair< RTreeRecord_NonLeaf, unsigned > t = std::make_pair( children_node, current_height-1);
1205 Q_nonleaf_records.push_back( t );
1208 special_case_bounding_box =
parent->children_nodes[ child_in_parent ].bounding_box;
1210 _RTREE_PRINT(
" CT3.1 delete in parent, position's record EN");
1213 _RTREE_PRINT(
" remove_record_from_parent error ");
1215 elimination_performed =
true;
1218 _RTREE_PRINT(
" CT4 ");
1220 elimination_performed =
false;
1225 _RTREE_PRINT(
" CT3 leaf: eliminate underfull node");
1228 _RTREE_PRINT(
" CT3.2 add N to Q " << position->
children_leaves.size() );
1231 _RTREE_PRINT(
" i " << i );
1232 Q_leaf_records.push_back( children_leave );
1233 special_case_bounding_box = children_leave.bounding_box;
1236 _RTREE_PRINT(
" CT3.1 delete in parent, position's record EN");
1239 _RTREE_PRINT(
" remove_record_from_parent error ");
1241 elimination_performed =
true;
1244 _RTREE_PRINT(
" CT4 ");
1246 elimination_performed =
false;
1249 _RTREE_PRINT(
" CT5 ");
1255 _RTREE_PRINT(
" ------ Q_leaf");
1256 for( std::vector< RTreeRecord_Leaf >::iterator it = Q_leaf_records.begin(); it != Q_leaf_records.end(); ++it ){
1257 _RTREE_PRINT(
" leaf:" << (*it).data);
1259 _RTREE_PRINT(
" ------ Q_nonleaf");
1260 for( std::vector< std::pair< RTreeRecord_NonLeaf, unsigned > >::iterator it = Q_nonleaf_records.begin(); it != Q_nonleaf_records.end(); ++it ){
1261 _RTREE_PRINT(
" ------- " << it->second );
1262 _RTREE_PRINT_TREE( it->first.data, 0);
1265 _RTREE_PRINT(
" CT6 ");
1266 for(
auto & Q_leaf_record : Q_leaf_records){
1268 _RTREE_PRINT(
" inserted leaf:" << (*it).data <<
" ------------");
1269 _RTREE_PRINT_TREE(
root, 0);
1273 for(
auto & Q_nonleaf_record : Q_nonleaf_records){
1275 _RTREE_PRINT(
" inserted nonleaf------------");
1276 _RTREE_PRINT_TREE(
root, 0);
1280 return root_elimination_performed;
1295 if(
child->children_nodes.size() > 0 ){
1296 _RTREE_PRINT(
" non-leaf: recalculate bounding box of parent ");
1297 parent->children_nodes[ child_in_parent ].bounding_box =
Rect(
child->children_nodes[0].bounding_box );
1298 for(
unsigned i=1; i <
child->children_nodes.size(); i++ ){
1299 parent->children_nodes[ child_in_parent ].bounding_box.unionWith(
child->children_nodes[i].bounding_box );
1303 _RTREE_PRINT(
" leaf: recalculate bounding box of parent ");
1304 parent->children_nodes[ child_in_parent ].bounding_box =
Rect(
child->children_leaves[0].bounding_box );
1306 for(
unsigned i=1; i <
child->children_leaves.size(); i++ ){
1307 parent->children_nodes[ child_in_parent ].bounding_box.unionWith(
child->children_leaves[i].bounding_box );
1322 _RTREE_PRINT(
"remove_record_from_parent)" );
1323 for( std::vector< RTreeRecord_NonLeaf >::iterator it =
parent->children_nodes.begin(); it!=
parent->children_nodes.end(); ++it ){
1324 if( it->data ==
child ){
1326 parent->children_nodes.erase( it );
C area() const
Compute the rectangle's area.
bool empty() const
Check for emptiness.
C area() const
Compute the rectangle's area.
bool contains(GenericRect< C > const &r) const
Check whether the rectangle includes all points in the given rectangle.
void unionWith(CRect const &b)
Enlarge the rectangle to contain the argument.
Axis-aligned rectangle that can be empty.
std::vector< RTreeRecord_Leaf > children_leaves
std::vector< RTreeRecord_NonLeaf > children_nodes
double find_waste_area(const Rect &a, const Rect &b) const
std::pair< RTreeNode *, bool > find_parent(RTreeNode *subtree_root, Rect search_area, RTreeNode *wanted) const
int remove_record_from_parent(RTreeNode *parent, RTreeNode *child)
void recalculate_bounding_box(RTreeNode *parent, RTreeNode *child, unsigned &child_in_parent)
bool adjust_tree(RTreeNode *position, std::pair< RTreeNode *, RTreeNode * > &node_division, bool split_performed)
std::pair< unsigned, enum_add_to_group > pick_next(RTreeNode *group_a, RTreeNode *group_b, RTreeNode *s, std::vector< bool > &assigned_v)
std::pair< unsigned, unsigned > pick_seeds(RTreeNode *s) const
RTreeNode * find_leaf(RTreeNode *subtree, const Rect &search_area, const int shape_to_delete) const
double find_enlargement(const Rect &a, const Rect &b) const
std::pair< RTreeNode *, RTreeNode * > split_node(RTreeNode *s)
bool condense_tree(RTreeNode *position)
std::pair< RTreeNode *, RTreeNode * > quadratic_split(RTreeNode *s)
int erase(const Rect &search_area, const int shape_to_delete)
void insert(Rect const &r, unsigned shape)
void print_tree(RTreeNode *subtree_root, int depth) const
RTreeNode * choose_node(const Rect &r, const bool &insert_high=false, const unsigned &stop_height=0) const
void sanity_check(RTreeNode *subtree_root, int depth, bool used_during_insert=false) const
RTreeRecord_NonLeaf create_nonleaf_record_from_rtreenode(Rect &new_entry_bounding, RTreeNode *rtreenode)
void copy_group_a_to_existing_node(RTreeNode *position, RTreeNode *group_a)
void search(const Rect &search_area, std::vector< int > *result, const RTreeNode *subtree) const
Axis aligned, non-empty rectangle.
static char const *const parent
Various utility functions.
std::vector< Point > intersect(const xAx &C1, const xAx &C2)
Implementation of Red-Black Tree as described in Intorduction to Algorithms.