Files Classes Functions Hierarchy
00001 #ifndef BSPTREED2_H 00002 #define BSPTREED2_H 00003 00004 #include <iostream> 00005 #include <vector> 00006 using namespace std; 00007 00008 #include <halfspaceD2.h> 00009 #include <linechopped.h> 00010 #include <treeindexedD2.h> 00011 #include <treeindexedD2iter.h> 00012 00013 template< typename PT, typename PD, typename INDX > 00014 class bsptreeD2find; 00015 00020 template< typename PT, typename PD, typename INDX > 00021 class bsptreeD2 00022 { 00023 public: 00024 00026 static PD tmin; 00028 static PD tmax; 00029 00033 treeindexedD2<INDX> tree; 00034 00037 vector< halfspaceD2<PT,PD> > vi; 00038 00040 boolc empty() const 00041 { return (vi.size()==1); } 00042 00044 bsptreeD2(); 00045 00047 void addroot( halfspaceD2<PT,PD> const & h ); 00049 void addleft 00050 ( 00051 INDX const mv, 00052 INDX const mvbitlength, 00053 halfspaceD2<PT,PD> const & h 00054 ); 00056 void addright 00057 ( 00058 INDX const mv, 00059 INDX const mvbitlength, 00060 halfspaceD2<PT,PD> const & h 00061 ); 00062 00065 void find( INDX & i, PT const & pt ); 00066 00071 template< typename treeindexedD2iterINDX > 00072 void clip 00073 ( 00074 PD & t0, 00075 PD & t1, 00076 PT const & La, 00077 PT const & Lm, 00078 treeindexedD2iterINDX const & i1 00079 ); 00080 00081 // <TODO> 00082 //void find( treeindexedD2node<> & khnd, bool & sees, PT const & pt ); 00083 00084 00100 istream & serializeInverse(istream & istr); 00101 00104 void find 00105 ( 00106 linechoppedindexed<PT,PD,INDX> & L, 00107 PT const & p0, 00108 PT const & p1 00109 ); 00110 00112 boolc validhalfspaces 00113 ( 00114 INDX & errorh, 00115 INDX & errorhparent 00116 ); 00117 00118 void visibility 00119 ( 00120 vector<INDX> & vnds, 00121 PT const & p0 00122 ) const; 00123 00124 private: 00125 00127 void visibility 00128 ( 00129 vector<INDX> & vnds, 00130 treeindexedD2node<INDX> const * nd, 00131 PT const & p0 00132 ) const; 00133 00134 boolc serializeInversePre 00135 ( 00136 istream & istr, 00137 bool & withindexes, 00138 uint & n 00139 ); 00140 00141 }; 00142 00143 00144 template< typename PT, typename PD, typename INDX > 00145 istream & operator >> (istream & istr, bsptreeD2<PT,PD,INDX> & x) 00146 { return x.serializeInverse(istr); } 00147 00148 00152 template< typename PT, typename PD, typename INDX > 00153 class bsptreeD2find 00154 { 00155 public: 00156 00158 bsptreeD2<PT,PD,INDX> & bsp; 00159 00162 vector< treeindexedD2node<INDX> * > path; 00163 00165 bsptreeD2find( bsptreeD2<PT,PD,INDX> & bsp_ ) 00166 : bsp(bsp_) {} 00167 00169 void find( INDX & i, PT const & pt ); 00170 00171 }; 00172 00173 00174 //--------------------------------------------------------- 00175 // Implementation 00176 00177 template< typename PT, typename PD, typename INDX > 00178 void bsptreeD2<PT,PD,INDX>::addroot( halfspaceD2<PT,PD> const & h ) 00179 { 00180 assert(vi.size()==1); 00181 00182 vi.push_back(h); 00183 } 00184 00185 template< typename PT, typename PD, typename INDX > 00186 void bsptreeD2<PT,PD,INDX>::addleft 00187 ( 00188 INDX const mv, 00189 INDX const mvbitlength, 00190 halfspaceD2<PT,PD> const & h 00191 ) 00192 { 00193 tree.move(mv,mvbitlength); 00194 tree.addleft(); 00195 vi.push_back(h); 00196 } 00197 00198 template< typename PT, typename PD, typename INDX > 00199 void bsptreeD2<PT,PD,INDX>::addright 00200 ( 00201 INDX const mv, 00202 INDX const mvbitlength, 00203 halfspaceD2<PT,PD> const & h 00204 ) 00205 { 00206 tree.move(mv,mvbitlength); 00207 tree.addright(); 00208 vi.push_back(h); 00209 } 00210 00211 00212 template< typename PT, typename PD, typename INDX > 00213 void bsptreeD2<PT,PD,INDX>::visibility 00214 ( 00215 vector<INDX> & vnds, 00216 PT const & p0 00217 ) const 00218 { 00219 vnds.clear(); 00220 00221 if (tree.root==0) 00222 return; 00223 00224 visibility(vnds,tree.root,p0); 00225 } 00226 00227 template< typename PT, typename PD, typename INDX > 00228 void bsptreeD2<PT,PD,INDX>::visibility 00229 ( 00230 vector<INDX> & vnds, 00231 treeindexedD2node<INDX> const * nd, 00232 PT const & p0 00233 ) const 00234 { 00235 assert(nd!=0); 00236 00237 // Is the node internal? 00238 if (nd->isleaf()==false) 00239 { 00240 halfspaceD2<PT,PD> const & h(vi[nd->index]); 00241 if (h.isInside(p0)) 00242 { 00243 visibility(vnds,nd->right,p0); 00244 visibility(vnds,nd->left,p0); 00245 } 00246 else 00247 { 00248 visibility(vnds,nd->left,p0); 00249 visibility(vnds,nd->right,p0); 00250 } 00251 } 00252 else 00253 vnds.push_back(nd->index); 00254 } 00255 00256 template< typename PT, typename PD, typename INDX > 00257 void bsptreeD2find<PT,PD,INDX>::find 00258 ( 00259 INDX & i, 00260 PT const & pt 00261 ) 00262 { 00263 treeindexedD2<INDX> & tree(bsp.tree); 00264 vector< halfspaceD2<PT,PD> > & vi(bsp.vi); 00265 00266 tree.reset(); 00267 00268 assert(tree.current!=0); 00269 00270 while (tree.current->isleaf() == false) 00271 { 00272 assert(tree.current->index < vi.size()); 00273 00274 path.push_back(tree.current); 00275 if (vi[tree.current->index].isInside(pt)) 00276 tree.moveleft(); 00277 else 00278 tree.moveright(); 00279 00280 assert(tree.current!=0); 00281 } 00282 00283 path.push_back(tree.current); 00284 i = tree.current->index; 00285 } 00286 00287 00288 00289 00290 template< typename PT, typename PD, typename INDX > 00291 template< typename treeindexedD2iterINDX > 00292 void bsptreeD2<PT,PD,INDX>::clip 00293 ( 00294 PD & t0, 00295 PD & t1, 00296 PT const & La, 00297 PT const & Lm, 00298 treeindexedD2iterINDX const & i1 00299 ) 00300 { 00301 INDX index; 00302 INDX index2; 00303 00304 uint sz = i1.path.size(); 00305 00306 if (sz<=1) 00307 return; 00308 00309 --sz; 00310 00311 //cout << SHOW(t0) << " " SHOW(t1) << " "; 00312 //cout << SHOW(La) << " " << SHOW(Lm) << endl; 00313 00314 for (uint i=0; i<sz; ++i) 00315 { 00316 //cout << SHOW(i1.path[i]->index) << endl; 00317 index = i1.path[i]->index; 00318 index2 = i1.path[i+1]->index; 00319 //cout << SHOW(index) << endl; 00320 //cout << SHOW(index2) << endl; 00321 00322 if ( i1.path[i]->isleftinternal(index2) ) 00323 vi[index].clip(t0,t1,La,Lm); 00324 else 00325 { 00326 if ( i1.path[i]->isrightinternal(index2) ) 00327 { 00328 vi[index].clipNeg(t0,t1,La,Lm); 00329 } 00330 else 00331 assert(false); 00332 } 00333 } 00334 00335 } 00336 00337 00338 template< typename PT, typename PD, typename INDX > 00339 boolc bsptreeD2<PT,PD,INDX>::serializeInversePre 00340 ( 00341 istream & istr, 00342 bool & withindexes, 00343 uint & n 00344 ) 00345 { 00346 withindexes=false; 00347 bool withindexestag(false); 00348 00349 string s; 00350 istr >> s; 00351 string::size_type pos=s.find("withindexes="); 00352 if (pos==string::npos) 00353 return istr; 00354 00355 s.erase(pos,12); 00356 if (s=="1") 00357 { 00358 withindexes=true; 00359 withindexestag=true; 00360 } 00361 00362 if (s=="true") 00363 { 00364 withindexes=true; 00365 withindexestag=true; 00366 } 00367 00368 if ((s=="0")||(s=="false")) 00369 withindexestag=true; 00370 00371 if (withindexestag==false) 00372 return false; 00373 00374 istr >> n; 00375 00376 if (n==0) 00377 return false; 00378 00379 return true; 00380 } 00381 00382 00383 template< typename PT, typename PD, typename INDX > 00384 boolc bsptreeD2<PT,PD,INDX>::validhalfspaces 00385 ( 00386 INDX & errorh, 00387 INDX & errorhparent 00388 ) 00389 { 00390 PT La; 00391 PT Lm; 00392 PT Lb; 00393 00394 PD t0; 00395 PD t1; 00396 00397 PD q0; 00398 PD q1; 00399 00400 for ( treeindexedD2iterinternal<INDX> i1(tree); 00401 !i1; ++i1 ) 00402 { 00403 halfspaceD2<PT,PD> & h1(vi[i1()->index]); 00404 00405 Lm = h1.p1-h1.p0; 00406 La = h1.p0; 00407 Lb = h1.p1; 00408 00409 t0 = tmin; 00410 t1 = tmax; 00411 00412 uint sz = i1.path.size(); 00413 if (sz==0) 00414 continue; 00415 00416 clip(t0,t1,La,Lm,i1); 00417 00418 line<PT,PD> L1(Lm,La); 00419 00420 //cout << SHOW(i1()->index) << endl; 00421 errorhparent = i1()->index; 00422 //cout << SHOW(errorhparent) << endl; 00423 00424 // If the left node is a half-space, test that it 00425 // intersects its parent. 00426 if (i1()->left->isleaf()==false) 00427 { 00428 errorh = i1()->left->index; 00429 00430 halfspaceD2<PT,PD> & h2(vi[i1()->left->index]); 00431 line<PT,PD> L2(h2.p1-h2.p0,h2.p0); 00432 if (L1.intersects(q0,q1,L2)==false) 00433 return false; 00434 00435 // Is q0 in [t0,t1]? 00436 if (q0<t0) 00437 return false; 00438 00439 if (q0>t1) 00440 return false; 00441 } 00442 00443 if (i1()->right->isleaf()==false) 00444 { 00445 errorh = i1()->right->index; 00446 00447 halfspaceD2<PT,PD> & h2(vi[i1()->right->index]); 00448 line<PT,PD> L2(h2.p1-h2.p0,h2.p0); 00449 if (L1.intersects(q0,q1,L2)==false) 00450 return false; 00451 00452 // Is q0 in [t0,t1]? 00453 if (q0<t0) 00454 return false; 00455 00456 if (q0>t1) 00457 return false; 00458 } 00459 } 00460 00461 return true; 00462 } 00463 00464 template< typename PT, typename PD, typename INDX > 00465 istream & bsptreeD2<PT,PD,INDX>::serializeInverse(istream & istr) 00466 { 00467 tree.construct(); 00468 00469 bool withindexes; 00470 uint n; 00471 if (serializeInversePre(istr,withindexes,n)==false) 00472 return istr; 00473 00474 PT p0; 00475 PT p1; 00476 00477 INDX i0; 00478 INDX i1; 00479 00480 treeindexedD2node<INDX> * parent; 00481 00482 istr >> p0; 00483 istr >> p1; 00484 vi.push_back(halfspaceD2<PT,PD>(p0,p1)); 00485 if (withindexes) 00486 { 00487 istr >> i0; 00488 istr >> i1; 00489 tree.root->left->index = i0; 00490 tree.root->right->index = i1; 00491 } 00492 00493 if (n==1) 00494 return istr; 00495 00496 INDX ifind; 00497 00498 bsptreeD2find<PT,PD,INDX> bspf(*this); 00499 00500 for (uint i=1; i<n; ++i) 00501 { 00502 istr >> p0; 00503 istr >> p1; 00504 vi.push_back(halfspaceD2<PT,PD>(p0,p1)); 00505 00506 //cout << SHOW( (stringc)tree ) << endl << endl; 00507 00508 bspf.find(ifind,p0); 00509 parent = bspf.path[ bspf.path.size()-2 ]; 00510 tree.current = parent; 00511 assert(parent!=0); 00512 00513 if ((ifind==parent->left->index)&&(parent->left->isleaf())) 00514 { 00515 tree.addleft(); 00516 00517 if (withindexes) 00518 { 00519 istr >> i0; 00520 istr >> i1; 00521 00522 tree.moveleft(); 00523 tree.current->left->index=i0; 00524 tree.current->right->index=i1; 00525 } 00526 00527 continue; 00528 } 00529 00530 if ((ifind==parent->right->index)&&(parent->right->isleaf())) 00531 { 00532 tree.addright(); 00533 00534 if (withindexes) 00535 { 00536 istr >> i0; 00537 istr >> i1; 00538 00539 tree.moveright(); 00540 tree.current->left->index=i0; 00541 tree.current->right->index=i1; 00542 } 00543 00544 continue; 00545 } 00546 00547 assert(false); 00548 } 00549 00550 //INDX errorh, errorhparent; 00551 //cout << SHOW(validhalfspaces(errorh,errorhparent)) << " "; 00552 //cout << SHOW(errorh) << " " << SHOW(errorhparent) << endl; 00553 00554 return istr; 00555 } 00556 00557 template< typename PT, typename PD, typename INDX > 00558 void bsptreeD2<PT,PD,INDX>::find( INDX & i, PT const & pt ) 00559 { 00560 tree.reset(); 00561 00562 assert(tree.current!=0); 00563 00564 while (tree.current->isleaf() == false) 00565 { 00566 assert(tree.current->index < vi.size()); 00567 if (vi[tree.current->index].isInside(pt)) 00568 tree.moveleft(); 00569 else 00570 tree.moveright(); 00571 00572 assert(tree.current!=0); 00573 } 00574 00575 i = tree.current->index; 00576 } 00577 00578 template< typename PT, typename PD, typename INDX > 00579 bsptreeD2<PT,PD,INDX>::bsptreeD2() 00580 { 00581 vi.push_back( halfspaceD2<PT,PD>() ); 00582 } 00583 00584 00585 template< typename PT, typename PD, typename INDX > 00586 void bsptreeD2<PT,PD,INDX>::find 00587 ( 00588 linechoppedindexed<PT,PD,INDX> & L, 00589 PT const & p0, 00590 PT const & p1 00591 ) 00592 { 00593 //<TODO> What is happening? 00594 assert(false); 00595 00596 L.ln.constructfromendpoints(p0,p1); 00597 L.chain.clear(); 00598 L.chain.push_back 00599 ( 00600 pointindexed< point2<PD>, INDX >( point2<PD>(0.0,1.0), (INDX)0) 00601 ); 00602 00603 } 00604 00605 00606 #endif 00607
1.5.8