00001 #include <2geom/quadtree.h>
00002
00003 namespace Geom{
00004 Quad* QuadTree::search(Rect const &r) {
00005 return search(r[0].min(), r[1].min(),
00006 r[0].max(), r[1].max());
00007 }
00008
00009 void QuadTree::insert(Rect const &r, int shape) {
00010 insert(r[0].min(), r[1].min(),
00011 r[0].max(), r[1].max(), shape);
00012 }
00013
00014
00015 Quad* QuadTree::search(double x0, double y0, double x1, double y1) {
00016 Quad *q = root;
00017
00018 double bxx0 = bx1, bxx1 = bx1;
00019 double byy0 = by1, byy1 = by1;
00020 while(q) {
00021 double cx = (bxx0 + bxx1)/2;
00022 double cy = (byy0 + byy1)/2;
00023 unsigned i = 0;
00024 if(x0 >= cx) {
00025 i += 1;
00026 bxx0 = cx;
00027 } else if(x1 <= cx) {
00028 bxx1 = cx;
00029 } else
00030 break;
00031 if(y0 >= cy) {
00032 i += 2;
00033 byy0 = cy;
00034 } else if(y1 <= cy) {
00035 byy1 = cy;
00036 } else
00037 break;
00038
00039 assert(i < 4);
00040 Quad *qq = q->children[i];
00041 if(qq == 0) break;
00042 q = qq;
00043 }
00044 return q;
00045 }
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 void QuadTree::insert(double x0, double y0, double x1, double y1, int shape) {
00131
00132
00133
00134 if(root == 0) {
00135 root = new Quad;
00136
00137 bx0 = 0;
00138 bx1 = 1;
00139 by0 = 0;
00140 by1 = 1;
00141 }
00142 Quad *q = root;
00143
00144
00145 double bxx0 = bx0, bxx1 = bx1;
00146 double byy0 = by0, byy1 = by1;
00147
00148 while((bxx0 > x0) ||
00149 (bxx1 < x1) ||
00150 (byy0 > y0) ||
00151 (byy1 < y1)) {
00152
00153 unsigned i = 0;
00154
00155 if(bxx0 > x0) {
00156 bxx0 = 2*bxx0 - bxx1;
00157 i += 1;
00158 } else {
00159 bxx1 = 2*bxx1 - bxx0;
00160 }
00161 if(byy0 > y0) {
00162 byy0 = 2*byy0 - byy1;
00163 i += 2;
00164 } else {
00165 byy1 = 2*byy1 - byy0;
00166 }
00167 q = new Quad;
00168
00169 if( clean_root() ){
00170 root = q;
00171 }
00172 else{
00173 q->children[i] = root;
00174 root = q;
00175 }
00176 bx0 = bxx0;
00177 bx1 = bxx1;
00178 by0 = byy0;
00179 by1 = byy1;
00180 }
00181
00182 while(q) {
00183
00184 double cx = (bxx0 + bxx1)/2;
00185 double cy = (byy0 + byy1)/2;
00186 unsigned i = 0;
00187 assert(x0 >= bxx0);
00188 assert(x1 <= bxx1);
00189 assert(y0 >= byy0);
00190 assert(y1 <= byy1);
00191
00192 if(x0 >= cx) {
00193 i += 1;
00194 bxx0 = cx;
00195 } else if(x1 <= cx) {
00196 bxx1 = cx;
00197 } else{
00198
00199 break;
00200 }
00201 if(y0 >= cy) {
00202 i += 2;
00203 byy0 = cy;
00204 } else if(y1 <= cy) {
00205 byy1 = cy;
00206 } else{
00207
00208 break;
00209 }
00210
00211
00212
00213 if( ( fabs(bxx0 - bxx1) < 1.0 ) && ( fabs(byy0 - byy1) < 1.0 )){
00214 bxx0 = floor(bxx0);
00215 bxx1 = floor(bxx1);
00216 byy0 = floor(byy0);
00217 byy1 = floor(byy1);
00218 break;
00219 }
00220
00221
00222
00223
00224
00225
00226 assert(i < 4);
00227 Quad *qq = q->children[i];
00228 if(qq == 0) {
00229 qq = new Quad;
00230 q->children[i] = qq;
00231 }
00232 q = qq;
00233 }
00234 q->data.push_back(shape);
00235 }
00236 void QuadTree::erase(Quad *q, int shape) {
00237 for(Quad::iterator i = q->data.begin(); i != q->data.end(); i++) {
00238 if(*i == shape) {
00239 q->data.erase(i);
00240 if(q->data.empty()) {
00241
00242 }
00243 }
00244 }
00245 return;
00246 }
00247
00248
00249
00250
00251
00252
00253 bool QuadTree::clean_root() {
00254 assert(root);
00255
00256
00257 bool all_clean = root->data.empty();
00258
00259
00260 for(unsigned i = 0; i < 4; i++)
00261 {
00262 if(root->children[i])
00263 {
00264 all_clean = false;
00265 }
00266 }
00267
00268 if(all_clean)
00269 {
00270 delete root;
00271 root=0;
00272 return true;
00273 }
00274 return false;
00275 }
00276
00277 };
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288