Changeset 5300
- Timestamp:
- 08/17/10 08:46:16 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/objects/Bamg/QuadTree.cpp
r5269 r5300 235 235 /*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, QuadTree.cpp/NearestVertex)*/ 236 236 237 /*Build QuadTree*/ 238 QuadTreeBox *pb[MaxDeep]; 239 int pi[MaxDeep]; 240 Icoor1 ii[MaxDeep]; 241 Icoor1 jj[MaxDeep]; 242 register int level; 243 register long n0; 244 register QuadTreeBox *b; 245 long h = MaxISize,h0; 246 long hb = MaxISize; 247 Icoor1 i0 = 0,j0=0; 248 249 /*initial nearest vertex pointer*/ 237 /*Intermediaries*/ 238 QuadTreeBox *pb[MaxDeep]; 239 int pi[MaxDeep]; 240 Icoor1 ii[MaxDeep]; 241 Icoor1 jj[MaxDeep]; 242 int level; 243 long n0; 244 QuadTreeBox *b; 245 long h0; 246 long h = MaxISize; 247 long hb= MaxISize; 248 Icoor1 i0=0,j0=0; 249 250 /*initial output as NULL (no vertex found)*/ 250 251 BamgVertex* nearest_v=NULL; 251 252 252 /*iplus= i projected in [0,MaxISize-1] (example: if i<0, i=0)*/ 253 Icoor1 iplus( i<MaxISize ? (i<0?0:i) : MaxISize-1); 254 /*jplus= j projected in [0,MaxISize-1] (example: if j>=MaxISize, j=MaxISize-1)*/ 255 Icoor1 jplus( j<MaxISize ? (j<0?0:j) : MaxISize-1); 253 /*Project w coordinates (i,j) onto [0,MaxISize-1] x [0,MaxISize-1] -> (iplus,jplus)*/ 254 Icoor1 iplus( i<MaxISize ? (i<0?0:i) : MaxISize-1); 255 Icoor1 jplus( j<MaxISize ? (j<0?0:j) : MaxISize-1); 256 256 257 257 /*Get initial Quadtree box (largest)*/ … … 261 261 if (!root->nbitems) return nearest_v; 262 262 263 /*else, find the nonempty QuadTreeBox containing the point (i,j)*/263 /*else, find the smallest non-empty QuadTreeBox containing the point (i,j)*/ 264 264 while((n0=b->nbitems)<0){ 265 265 266 //shifted righ by one bit: hb2=01000000 -> 00100000 267 register Icoor1 hb2 = hb >> 1; 268 //Get QuadTreeBox number of size hb2 containing i;j (Macro) 269 register int k = IJ(iplus,jplus,hb2); 270 //Get the corresponding box b0 271 register QuadTreeBox* b0=b->b[k]; 272 273 /* break if NULL box or empty*/ 266 Icoor1 hb2 = hb >> 1; //size of the current box 267 int k = IJ(iplus,jplus,hb2); //box number (0,1,2 or 3) 268 QuadTreeBox *b0 = b->b[k]; //pointer toward current box 269 270 /* break if NULL box or empty (Keep previous box b)*/ 274 271 if (( b0 == NULL) || (b0->nbitems == 0)) break; 275 272 276 /*Get next Qu dtree box*/273 /*Get next Quadtree box*/ 277 274 b=b0; 278 275 i0 += I_IJ(k,hb2); // i orign of QuadTreeBox (macro) … … 280 277 hb = hb2; // size of the box (in Int) 281 278 } 279 280 /*The box b, is the smallest box containing the point (i,j) and 281 * has the following properties: 282 * - n0: number of items (>0 if vertices, else boxes) 283 * - hb: box size (int) 284 * - i0: x coordinate of the lower left corner 285 * - j0: y coordinate of the lower left corner*/ 282 286 283 287 /* if the current subbox is holding vertices, we are almost done*/ … … 298 302 } 299 303 } 304 /*return closest vertex*/ 300 305 return nearest_v; 301 306 } 302 307 303 /* general case: the current box is empty, we have to g etbackwards308 /* general case: the current box is empty, we have to go backwards 304 309 and find the closest not-empty box and find the closest vertex*/ 305 310 306 / /initialize pb pi ii and jj307 pb[0]=b; //pointer toward the box b308 pi[0]=b->nbitems>0? 309 ii[0]=i0; // i coordinate of the box310 jj[0]=j0; // j coordinate of the box311 312 / /initialize h as hb311 /*Initialize search variables*/ 312 pb[0]=b; //pointer toward the box b 313 pi[0]=b->nbitems>0?(int)b->nbitems:4;//number of boxes in b 314 ii[0]=i0; //i coordinate of the box lowest left corner 315 jj[0]=j0; //j coordinate of the box lowest left corner 316 317 /*initialize h: smallest box size, containing a vertex close to w*/ 313 318 h=hb; 314 319 315 /* loop, until level=0 (main quadtree box)*/320 /*Main loop*/ 316 321 level=0; 317 322 do { … … 321 326 322 327 /*Loop over the items in current box (if not empty!)*/ 323 while (pi[level]--){ 324 325 /*k = number of items in the box*/ 328 while (pi[level]){ 329 330 /*We are looping now over the items of b. k is the current index (in [0 3])*/ 331 pi[level]--; 326 332 int k=pi[level]; 327 333 328 /*if the current subbox is holding vertices */334 /*if the current subbox is holding vertices (b->nbitems<0 is subboxes)*/ 329 335 if (b->nbitems>0){ 330 336 I2 i2=b->v[k]->i; … … 335 341 } 336 342 } 337 /*else: current box b is pointing toward 4 boxes (There must be a vertex at some point)*/ 343 /*else: current box b is pointing toward 4 boxes 344 * test sub-box k and go deeper into the tree if it is non empty 345 * and contains the point w modulo a size h that is either the size of the smallest 346 * non empty box containing w, or the closest point to w (so far) */ 338 347 else{ 339 348 QuadTreeBox* b0=b; 340 349 341 / /if the next box exists:350 /*if the next box exists:*/ 342 351 if (b=b->b[k]){ 343 352 344 /*Get size (hb) and coordinates of the current sub-box */353 /*Get size (hb) and coordinates of the current sub-box lowest left corner*/ 345 354 hb>>=1; 346 355 Icoor1 iii = ii[level]+I_IJ(k,hb); 347 356 Icoor1 jjj = jj[level]+J_IJ(k,hb); 348 357 349 /*if the current point (iplus,jplus) is in b,go to next box*/ 358 /*if the current point (iplus,jplus) is in b (modulo h), this box is good: 359 * it is holding vertices that are close to w */ 350 360 if (INTER_SEG(iii,iii+hb,iplus-h,iplus+h) && INTER_SEG(jjj,jjj+hb,jplus-h,jplus+h)){ 351 pb[++level]= b; 361 level++; 362 pb[level]= b; 352 363 pi[level]= b->nbitems>0 ?(int) b->nbitems : 4 ; 353 364 ii[level]= iii; … … 362 373 } 363 374 } 364 /*Go backwards*/365 375 else{ 376 /*Current box is NULL, go to next subbox of b (k=k-1)*/ 366 377 b=b0; 367 378 } … … 369 380 } 370 381 371 / /else go backwards372 //shifted righ by one bit: hb=001000000 -> 01000000382 /*We have found a vertex, now, let's try the other boxes of the previous level 383 * in case there is a vertex closest to w that has not yet been tested*/ 373 384 hb <<= 1; 374 385 } while (level--);
Note:
See TracChangeset
for help on using the changeset viewer.