shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/cell2d.hpp
Go to the documentation of this file.
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