shape_doc 0.1
|
00001 00002 /***************************************************************************** 00003 * M a t h e m a g i x 00004 ***************************************************************************** 00005 * Cell 00006 * 2008-03-20 00007 * Julien Wintz & Bernard Mourrain 00008 ***************************************************************************** 00009 * Copyright (C) 2008 INRIA Sophia-Antipolis 00010 ***************************************************************************** 00011 * Comments : 00012 ****************************************************************************/ 00013 # ifndef shape_cell2d_hpp 00014 # define shape_cell2d_hpp 00015 00016 00017 # include <realroot/Seq.hpp> 00018 # include <shape/point.hpp> 00019 # include <shape/edge.hpp> 00020 # include <shape/bounding_box.hpp> 00021 # include <shape/cell.hpp> 00022 # include <shape/graph.hpp> 00023 00024 # define TMPL template<class C, class V> 00025 # define TMPL1 template<class V> 00026 # define SELF cell2d<C,V> 00027 # define REF REF_OF(V) 00028 # undef Topology 00029 # undef Topology2d 00030 # undef Point 00031 # undef Edge 00032 //==================================================================== 00033 namespace mmx { 00034 namespace shape { 00035 00036 TMPL struct topology2d; 00037 TMPL struct cell2d; 00038 00039 // TMPL struct with_cell2d { 00040 // typedef cell2d<K> Cell2d; 00041 // typedef topology2d<K> Topology2d; 00042 // }; 00043 00044 // TMPL struct cell2d_def 00045 // :public cell_def<K> 00046 // ,public with_cell2d<K> 00047 // {}; 00048 //-------------------------------------------------------------------- 00049 //struct cell2d_def {}; 00050 // template<> struct use<cell2d_def> 00051 // :public use<cell_def> { 00052 // typedef cell2d<double> Cell2d; 00053 // }; 00054 //-------------------------------------------------------------------- 00055 TMPL 00056 class cell2d : public cell<C,REF> { 00057 public: 00058 00059 typedef topology<C,V> Topology; 00060 // typedef typename use<cell2d_def,K>::Topology2d Topology2d; 00061 00062 typedef typename topology<C,V>::Point Point; 00063 typedef typename topology<C,V>::Edge Edge; 00064 typedef bounding_box<C,REF> BoundingBox; 00065 typedef cell<C,REF> Cell; 00066 00067 cell2d(void) ; 00068 cell2d(const BoundingBox & bx): Cell(bx) {} 00069 cell2d(double xmin, double xmax): Cell(xmin,xmax) {}; 00070 cell2d(double xmin, double xmax, double ymin, double ymax): Cell(xmin,xmax,ymin,ymax) {} ; 00071 00072 00073 virtual ~cell2d(void) ; 00074 00075 // virtual bool is_active (void) const = 0; 00076 // virtual bool is_regular (void) = 0; 00077 // virtual bool is_intersected (void) = 0; 00078 00079 //virtual int subdivide(SELF*& left, SELF*& right); 00080 //virtual void subdivide(SELF*& left, SELF*& right, int v, double s)=0; 00081 00082 virtual void split_position(int& v, double& t); 00083 00084 virtual Point* pair(Point * p, int & sgn)=0 ; 00085 virtual Point* starting_point( int sgn)=0 ; 00086 00087 bool is_corner (void) const ; 00088 00089 virtual unsigned nb_intersect(void) const { 00090 return (this->n_intersections.size()+ 00091 this->s_intersections.size()+ 00092 this->e_intersections.size()+ 00093 this->w_intersections.size() ); 00094 } 00095 00096 virtual Seq<Point *> intersections() const{ 00097 Seq<Point *> r; 00098 r<< this->s_intersections; 00099 r<< this->e_intersections; 00100 r<< this->n_intersections.reversed(); 00101 r<< this->w_intersections.reversed(); 00102 return ( r ); 00103 } 00104 00105 virtual Seq<Point *> intersections(int i) const{ 00106 switch(i) { 00107 case 0: 00108 return s_intersections; 00109 case 1: 00110 return e_intersections; 00111 case 2: 00112 return n_intersections.reversed(); 00113 case 3: 00114 return w_intersections.reversed(); 00115 default: 00116 return (Seq<Point *>()); 00117 } 00118 00119 } 00120 00121 inline bool is_border(void) const { 00122 return ( this->s_neighbors.size()==0 || 00123 this->e_neighbors.size()==0 || 00124 this->n_neighbors.size()==0 || 00125 this->w_neighbors.size()==0 ); 00126 } 00127 00128 00129 Seq<Point *> s_intersections ; 00130 Seq<Point *> e_intersections ; 00131 Seq<Point *> n_intersections ; 00132 Seq<Point *> w_intersections ; 00133 Seq<Point *> m_singular ; 00134 00135 /* Adjacency information */ 00136 00137 /*Pointer to graph instance of this cell*/ 00138 gNode<cell2d*>* m_gnode; 00139 00140 int side(Point *p) { 00141 Seq<Point*> all; 00142 int s,i,a; 00143 s = s_intersections.size(); 00144 all = this->intersections(); 00145 a = all.size(); 00146 i = all.search(p); 00147 if (i==-1) return (-1); 00148 else return 00149 ( i<s ? 0 : 00150 ( i<s+(int)e_intersections.size() ? 1 : 00151 ( i<a-(int)w_intersections.size() ? 2 : 00152 3 ))); 00153 } 00154 00155 inline void disconnect(); 00156 inline void connect0(SELF * a, SELF * b); 00157 inline void connect1(SELF * a, SELF * b) ; 00158 inline void join0( SELF * b) ; 00159 inline void join1( SELF * b) ; 00160 00161 00162 virtual Seq<cell2d *> neighbors() { 00163 Seq<cell2d *> r; 00164 r<< this->s_neighbors; 00165 r<< this->e_neighbors; 00166 r<< this->n_neighbors; 00167 r<< this->w_neighbors; 00168 return ( r ); } 00169 00170 Seq<cell2d *> s_neighbors ; 00171 Seq<cell2d *> e_neighbors ; 00172 Seq<cell2d *> n_neighbors ; 00173 Seq<cell2d *> w_neighbors ; 00174 00175 virtual cell2d * neighbor(Point * p) { 00176 foreach( cell2d *c, this->s_neighbors ) 00177 if ( c->n_intersections.member(p) ) 00178 { 00179 return c; 00180 } 00181 foreach( cell2d *c, this->e_neighbors ) 00182 if ( c->w_intersections.member(p) ) 00183 { 00184 return c; 00185 } 00186 foreach( cell2d *c, this->n_neighbors ) 00187 if ( c->s_intersections.member(p) ) 00188 { 00189 return c; 00190 } 00191 foreach( cell2d *c, this->w_neighbors ) 00192 if ( c->e_intersections.member(p) ) 00193 { 00194 return c; 00195 } 00196 00197 // Point p on boundary. 00198 //std::cout<<"... Point ("<<p->x()<<","<<p->y()<<") not found on neighbors of "<< this<<"("<<this->neighbors().size() <<")"<<std::endl; 00199 return NULL; 00200 } 00201 00202 }; 00203 00204 TMPL void 00205 SELF::split_position(int& v, double& s) { 00206 double sx = (this->xmax()-this->xmin()); 00207 double sy = (this->ymax()-this->ymin()); 00208 if(sx<sy) { 00209 v=1; 00210 s=(this->ymax()+this->ymin())/2; 00211 } else { 00212 v=0; 00213 s=(this->xmax()+this->xmin())/2; 00214 } 00215 } 00216 00217 TMPL SELF::cell2d(void) { } 00218 00219 TMPL SELF::~cell2d(void) {} 00220 00221 // TMPL bool 00222 // SELF::insert_regular(Topology* t) { 00223 // Topology2d* s= dynamic_cast<Topology2d*>(t); 00224 // int n0=s->nbv(); 00225 00226 // foreach(Point* p, this->n_intersections) s->insert(p); 00227 // foreach(Point* p, this->e_intersections) s->insert(p); 00228 // foreach(Point* p, this->s_intersections) s->insert(p); 00229 // foreach(Point* p, this->w_intersections) s->insert(p); 00230 00231 // if(s->nbv()> n0) 00232 // for(int i=n0; i<((int)s->nbv()-1);i+=2) { 00233 // s->insert( s->vertices(i),s->vertices(i+1) ) ; 00234 // //s->m_edges << new Edge(s->vertices(i),s->vertices(i+1)); 00235 // } 00236 // return true; 00237 // } 00238 00239 00240 // TMPL bool 00241 // SELF::insert_singular(Topology* t) { 00242 // unsigned ni= this->nb_intersect() ; 00243 00244 // // std::cout<<"singular cell with "<<ni<<" pts"<<std::endl; 00245 00246 // if(ni>1) 00247 // t->insert((BoundingBox*)this,true); 00248 // else 00249 // t->insert((BoundingBox*)this,false); 00250 00251 // if(this->m_singular.size()>0) { 00252 // Topology2d* s= dynamic_cast<Topology2d*>(t); 00253 // Point *c=this->m_singular[0]; 00254 // s->m_specials<<c; 00255 // foreach(Point* p, this->n_intersections) s->insert(new Edge(p,c)); 00256 // foreach(Point* p, this->e_intersections) s->insert(new Edge(p,c)); 00257 // foreach(Point* p, this->s_intersections) s->insert(new Edge(p,c)); 00258 // foreach(Point* p, this->w_intersections) s->insert(new Edge(p,c)); 00259 // } 00260 // return true; 00261 // } 00262 00265 00266 TMPL inline void 00267 SELF::join0(SELF * b) //left,right 00268 { 00269 this->e_neighbors << b; 00270 b->w_neighbors << this; 00271 } 00272 00273 TMPL inline void 00274 SELF::join1(SELF * b) //up,down 00275 { 00276 b->s_neighbors << this; 00277 this->n_neighbors << b; 00278 } 00279 00280 TMPL inline void 00281 SELF::connect0(SELF * a, SELF * b) 00282 { 00283 int i; 00284 bool flag; 00285 00286 //copy horizontally 00287 b->e_neighbors= this->e_neighbors ; 00288 foreach(SELF* cl,b->e_neighbors) { 00289 i= cl->w_neighbors.search(this); 00290 cl->w_neighbors[i]= b; 00291 } 00292 a->w_neighbors= this->w_neighbors ; 00293 foreach(SELF* cl,a->w_neighbors) { 00294 i= cl->e_neighbors.search(this); 00295 cl->e_neighbors[i]= a; 00296 } 00297 00298 //update vertically 00299 foreach(SELF* cl,this->s_neighbors) { 00300 flag=false; 00301 if ( check_overlap(cl,a,0)) 00302 { 00303 //assert( cl->ymax()== a->ymin() ); 00304 a->s_neighbors<< cl; 00305 i= cl->n_neighbors.search(this); 00306 cl->n_neighbors[i]= a; 00307 flag=true; 00308 } 00309 if ( check_overlap(cl,b,0) ) 00310 { 00311 //assert( cl->ymax()== b->ymin() ); 00312 b->s_neighbors<< cl; 00313 if (!flag) 00314 { 00315 i= cl->n_neighbors.search(this); 00316 cl->n_neighbors[i]= b; 00317 } 00318 else 00319 cl->n_neighbors << b; 00320 } 00321 } 00322 foreach(SELF* cl,this->n_neighbors) { 00323 flag=false; 00324 if ( check_overlap(cl,a,0)) 00325 { 00326 a->n_neighbors<< cl; 00327 i= cl->s_neighbors.search(this); 00328 cl->s_neighbors[i]= a; 00329 flag=true; 00330 } 00331 if ( check_overlap(cl,b,0) ) 00332 { 00333 b->n_neighbors<< cl; 00334 if (!flag) 00335 { 00336 i= cl->s_neighbors.search(this); 00337 cl->s_neighbors[i]= b; 00338 } 00339 else 00340 cl->s_neighbors << b; 00341 } 00342 } 00343 } 00344 00345 TMPL inline void 00346 SELF::connect1(SELF * a, SELF * b) 00347 { 00348 int i; 00349 bool flag; 00350 00351 //copy vertically 00352 a->s_neighbors= this->s_neighbors ; 00353 foreach(SELF* cl,a->s_neighbors) { 00354 i= cl->n_neighbors.search(this); 00355 cl->n_neighbors[i]= a; 00356 } 00357 b->n_neighbors= this->n_neighbors ; 00358 foreach(SELF* cl,b->n_neighbors) { 00359 i= cl->s_neighbors.search(this); 00360 cl->s_neighbors[i]= b; 00361 } 00362 00363 //update horizontally 00364 foreach(SELF* cl,this->w_neighbors) { 00365 flag=false; 00366 if ( check_overlap(cl,a,1)) 00367 { 00368 //assert( cl->xmax()== a->xmin() ); 00369 a->w_neighbors<< cl; 00370 i= cl->e_neighbors.search(this); 00371 cl->e_neighbors[i]= a; 00372 flag=true; 00373 } 00374 if ( check_overlap(cl,b,1) ) 00375 { 00376 //assert( cl->xmax()== b->xmin() ); 00377 b->w_neighbors<< cl; 00378 if (!flag) 00379 { 00380 i= cl->e_neighbors.search(this); 00381 cl->e_neighbors[i]= b; 00382 } 00383 else 00384 cl->e_neighbors << b; 00385 } 00386 } 00387 foreach(SELF* cl,this->e_neighbors) { 00388 flag=false; 00389 if ( check_overlap(cl,a,1)) 00390 { 00391 a->e_neighbors<< cl; 00392 i= cl->w_neighbors.search(this); 00393 cl->w_neighbors[i]= a; 00394 flag=true; 00395 } 00396 if ( check_overlap(cl,b,1) ) 00397 { 00398 b->e_neighbors<< cl; 00399 if (!flag) 00400 { 00401 i= cl->w_neighbors.search(this); 00402 cl->w_neighbors[i]= b; 00403 } 00404 else 00405 cl->w_neighbors << b; 00406 } 00407 } 00408 } 00409 00410 TMPL 00411 inline bool check_overlap(SELF * a, SELF * b, int v) //left,right or up,down 00412 {// check if a,b overlap wrt v-th coordinate 00413 if (v==0) //direction v=0 00414 return !( a->xmax()<= b->xmin() || 00415 b->xmax()<= a->xmin() ); 00416 else //direction v=1 00417 return !( a->ymax()<= b->ymin() || 00418 b->ymax()<= a->ymin() ); 00419 } 00420 00421 TMPL inline void 00422 SELF::disconnect() 00423 { 00424 this->e_neighbors.clear(); 00425 this->w_neighbors.clear(); 00426 this->n_neighbors.clear(); 00427 this->s_neighbors.clear(); 00428 } 00429 00430 TMPL bool 00431 SELF::is_corner() const { 00432 00433 if (this->s_neighbors.size()==0 && 00434 this->e_neighbors.size()==0 ) 00435 return true; 00436 else if (this->e_neighbors.size()==0 && 00437 this->n_neighbors.size()==0 ) 00438 return true; 00439 else if (this->n_neighbors.size()==0 && 00440 this->w_neighbors.size()==0 ) 00441 return true; 00442 else if (this->w_neighbors.size()==0 && 00443 this->s_neighbors.size()==0 ) 00444 return true; 00445 00446 return false; 00447 } 00448 00449 00450 TMPL 00451 inline void print_neighbors(SELF * a) //for testing 00452 { 00453 std::cout<< "Cell : " << a <<std::endl; 00454 std::cout<< "EAST, " <<a->e_neighbors.size() << std::endl; 00455 foreach(SELF* cl,a->e_neighbors) 00456 std::cout<< cl << std::endl; 00457 std::cout<< "WEST, " <<a->w_neighbors.size() << std::endl; 00458 foreach(SELF* cl,a->w_neighbors) 00459 std::cout<< cl << std::endl; 00460 std::cout<< "NORTH, " <<a->n_neighbors.size() << std::endl; 00461 foreach(SELF* cl,a->n_neighbors) 00462 std::cout<< cl << std::endl; 00463 std::cout<< "SOUTH, " <<a->s_neighbors.size() <<std::endl; 00464 foreach(SELF* cl,a->s_neighbors) 00465 std::cout<< cl << std::endl; 00466 } 00467 00468 TMPL 00469 inline void print_intersections(SELF * a) //for testing 00470 { 00471 typedef typename topology<C,V>::Point Point; 00472 std::cout<< "Cell : " << a <<std::endl; 00473 std::cout<< "EAST, " <<a->e_intersections.size() << std::endl; 00474 foreach(Point* cl,a->e_intersections) 00475 std::cout<< cl->x()<<" "<<cl->y() << std::endl; 00476 std::cout<< "WEST, " <<a->w_intersections.size() << std::endl; 00477 foreach(Point* cl,a->w_intersections) 00478 std::cout<< cl->x()<<" "<<cl->y() << std::endl; 00479 std::cout<< "NORTH, " <<a->n_intersections.size() << std::endl; 00480 foreach(Point* cl,a->n_intersections) 00481 std::cout<< cl->x()<<" "<<cl->y() << std::endl; 00482 std::cout<< "SOUTH, " <<a->s_intersections.size() <<std::endl; 00483 foreach(Point* cl,a->s_intersections) 00484 std::cout<< cl->x()<<" "<<cl->y() << std::endl; 00485 } 00486 00487 00488 } ; // namespace shape 00489 } ; // namespace mmx 00490 # undef TMPL 00491 # undef TMPL1 00492 # undef SELF 00493 # endif // shape_cell2d_hpp