shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/cell2d_list.hpp
Go to the documentation of this file.
00001 /*****************************************************************************
00002  * M a t h e m a  g i x
00003  *****************************************************************************
00004  * Cell
00005  * 2008-03-20
00006  * Julien Wintz & Bernard Mourrain
00007  *****************************************************************************
00008  *               Copyright (C) 2008 INRIA Sophia-Antipolis
00009  *****************************************************************************
00010  * Comments :
00011  ****************************************************************************/
00012 
00013 # ifndef shape_cell2d_List_hpp
00014 # define shape_cell2d_List_hpp
00015 
00016 # include <shape/topology.hpp>
00017 # include <shape/cell_list.hpp>
00018 # include <shape/cell2d_algebraic_curve.hpp>
00019 # include <shape/solver_implicit.hpp>
00020 
00021 # define TMPL template<class C, class V>
00022 # define Shape geometric<V>
00023 # define Cell2dAlgebraicCurve cell2d_algebraic_curve<C,V>
00024 # define Intersection2dFactory intersection2d_factory<C,V>
00025 # define Solver     solver_implicit<C,V>
00026 
00027 # define Cell       cell<C,V>
00028 # define Cell2d     cell2d<C,V>
00029 # define CellList   cell_list<C,V>
00030 # define Cell2dList cell2d_list<C,V>
00031 namespace mmx {
00032 namespace shape {
00033 
00034 
00035 TMPL
00036 class cell2d_list: public cell2d<C,V>   {
00037 public:
00038   typedef typename Cell::BoundingBox  BoundingBox;
00039   typedef typename cell2d<C,V>::Point   Point;
00040   typedef topology<C,V>                 Topology;
00041 
00042   cell2d_list(void) ;
00043   cell2d_list(double xmin, double xmax) ;
00044   cell2d_list(double xmin, double xmax, double ymin, double ymax) ;
00045   cell2d_list(double xmin, double xmax, double ymin, double ymax, bool itr) ;
00046   cell2d_list(const BoundingBox& bx);
00047   virtual ~cell2d_list(void) ;
00048 
00049   virtual bool is_regular (void) ;// = 0 ;
00050   virtual bool is_active  (void) ;// = 0 ;
00051   virtual bool is_intersected(void) ;// = 0 ;
00052 
00053   virtual bool insert_regular(Topology*);// = 0 ;
00054   virtual bool insert_singular(Topology*);// = 0 ;
00055 
00056   virtual void subdivide     (Cell*& left, Cell*& right, int v, double s);
00057 
00058   virtual void split_position(int& v, double& t); 
00059 
00060   virtual Point* pair(Point * p, int & sgn);
00061   virtual Point* starting_point( int sgn);
00062 
00063   virtual bool  is_touching (void) {return true; };
00064 
00065   virtual unsigned nb_intersect(void) const;
00066 
00067     //Seq<Cell2d *>  neighbors();
00068     Cell2d * neighbor(Point * p);
00069   Seq<Point *> intersections() const;
00070 
00071   virtual Seq<Point *> intersections(int i) const{
00072       Seq<Point*> l;
00073       Cell2dAlgebraicCurve* c;
00074       
00075       foreach(Cell*m, this->m_objects)
00076       {
00077           c = dynamic_cast<Cell2dAlgebraicCurve*>(m);
00078           l<< c->intersections(i);
00079       }
00080       return l;
00081   }
00082 
00083 
00084   void push_back(Cell * cv) { m_objects.push_back(cv); }; 
00085   int  count(void) { return m_objects.size() ; }
00086 
00087 protected:
00088   Seq<Cell *>        m_objects  ;
00089 
00090   //Seq<Point*>        m_singulars;
00091   bool               m_intersected;
00092 
00093 private:
00094 
00095  template<int i> static bool 
00096  coord(Point*u,Point*v) { return ( (*u)[i]< (*v)[i]); }
00097   
00098 } ;
00099 
00100 //--------------------------------------------------------------------
00101 
00102 TMPL
00103 class intersection2d_factory {
00104 public:
00105   typedef bounding_box<C,V>      BoundingBox;
00106   typedef typename cell2d<C,V>::Point Point;
00107   static Intersection2dFactory * instance(void) {
00108 
00109         if(!m_instance)
00110             m_instance = new Intersection2dFactory ;
00111 
00112         return m_instance ;
00113     }
00114 
00115   void compute(Seq<Point*>& res, Shape * c1, Shape * c2, const BoundingBox& bx) {
00116     
00117     if(Cell2dAlgebraicCurve * ca1 = dynamic_cast<Cell2dAlgebraicCurve *>(c1)) {
00118       if(Cell2dAlgebraicCurve * ca2 = dynamic_cast<Cell2dAlgebraicCurve *>(c2)) {
00119 
00120         typedef polynomial< double, with<Bernstein> > MultivariateDenseBernstein;
00121         MultivariateDenseBernstein p1, p2;
00122         let::assign(p1.rep(), ca1->m_polynomial.rep() );
00123         let::assign(p2.rep(), ca2->m_polynomial.rep() );
00124         Solver::intersection(res, p1, p2, bx);
00125       }
00126     }
00127   }
00128 
00129 private:
00130     intersection2d_factory(void) {} ;
00131 
00132 private:
00133     static Intersection2dFactory * m_instance;
00134 } ;
00135 
00136 TMPL Intersection2dFactory*  Intersection2dFactory::m_instance = NULL;
00137 
00138 
00139 TMPL
00140 Cell2dList::cell2d_list(void): m_intersected(false) {}
00141 
00142 TMPL
00143 Cell2dList::cell2d_list(double xmin, double xmax, double ymin, double ymax) :  cell2d<C,V>(xmin, xmax, ymin, ymax), m_intersected(false) {}
00144 
00145 TMPL
00146 Cell2dList::cell2d_list(double xmin, double xmax, double ymin, double ymax, bool itr) : cell2d<C,V>(xmin, xmax, ymin, ymax), m_intersected(itr) {}
00147 
00148 TMPL
00149 Cell2dList::cell2d_list(const BoundingBox& bx): cell2d<C,V>(bx), m_intersected(false)  {};
00150 
00151 TMPL
00152 Cell2dList::~cell2d_list(void) {
00153     foreach (Cell* m, this->m_objects) delete m;
00154 }
00155   
00156 TMPL bool 
00157 Cell2dList::is_regular(){
00158   foreach (Cell* m, this->m_objects) 
00159     if(!m-> is_regular()) return false;
00160 
00161   if ( is_intersected() )
00162       return ( (this->m_singular.size()<2) &&
00163                (this->nb_intersect()<5) );
00164   else
00165       return (this->nb_intersect()<3) ;
00166 }
00167 
00168 TMPL bool 
00169 Cell2dList::is_intersected() {
00170   
00171   if(this->m_objects.size() >1 && !m_intersected) {
00172       //std::cout<<"Intersecting inside box "<< this <<std::endl;
00173       for(unsigned i=0; i<this->m_objects.size();i++)
00174           for(unsigned j=i+1; j<this->m_objects.size(); j++)
00175             Intersection2dFactory::instance()->compute(this->m_singular, (Shape*)this->m_objects[i], (Shape*)this->m_objects[j], (BoundingBox)*this);
00176       m_intersected = true;      
00177   }
00178   
00179   if (this->m_singular.size() > 0) return true;
00180   return false;
00181 }
00182 
00183 
00184 TMPL bool 
00185 Cell2dList::insert_regular(Topology* s) {
00186   foreach(Cell*  m, this->m_objects)   m->insert_regular(s);
00187   if (this->m_singular.size() > 0) 
00188     foreach(Point* p, this->m_singular) s->insert_singular(p);
00189   return true;
00190 }
00191   
00192 TMPL bool 
00193 Cell2dList::insert_singular(Topology* s) {
00194   //s->singular(this);
00195   foreach(Cell * m, this->m_objects) m->insert_singular(s);
00196   return true;
00197 }
00198 TMPL void
00199 Cell2dList::split_position(int& v, double& s) {
00200   double sx = (this->xmax()-this->xmin());
00201   double sy = (this->ymax()-this->ymin());
00202   if(sx<sy) {
00203     v=1;
00204     s=(this->ymax()+this->ymin())/2;
00205   } else {
00206     v=0;
00207     s=(this->xmax()+this->xmin())/2;
00208   }
00209 }
00210 
00211 TMPL void
00212 Cell2dList::subdivide(Cell *& left, Cell *& right, int  v, double c) {
00213 
00214   typedef Cell2dList Cell_t;
00215 
00216   if(v==1) {
00217     left =(Cell*)new Cell_t(this->xmin(), this->xmax(), this->ymin(), c, m_intersected) ;
00218     right=(Cell*)new Cell_t(this->xmin(), this->xmax(), c, this->ymax(), m_intersected) ;
00219     
00220     foreach(Point * p, this->m_singular) {
00221       if(p->y() <=  c) 
00222         ((Cell_t*) left)->m_singular << p ;
00223       else
00224         ((Cell_t*)right)->m_singular << p ;
00225     }
00226 
00227     /*  Update neighbors  */
00228     this->connect1( (Cell_t*)left, (Cell_t*)right);
00229     ((Cell_t*)left)->join1((Cell_t*)right);
00230 
00231   } else {//v==0
00232     left = (Cell*)new Cell_t(this->xmin(), c, this->ymin(), this->ymax(), m_intersected) ;
00233     right= (Cell*)new Cell_t(c, this->xmax(), this->ymin(), this->ymax(), m_intersected) ;
00234 
00235     foreach(Point * p, this->m_singular) {
00236       if(p->x() <= c ) 
00237         ((Cell_t*)left)->m_singular << p ;
00238       else
00239         ((Cell_t*)right)->m_singular << p ;
00240     }
00241 
00242     /*  Update neighbors  */
00243     this->connect0((Cell_t*)left, (Cell_t*)right);
00244     ((Cell_t*)left)->join0((Cell_t*)right);
00245 
00246   }
00247 
00248   /* disconnect parent */
00249   this->disconnect( );
00250 
00251   Cell * cv_left, * cv_right;
00252   foreach(Cell* cv, this->m_objects) {
00253       cv->subdivide( cv_left, cv_right);
00254     if(cv_left->is_active())
00255         ((Cell_t*)left)->m_objects<<cv_left;
00256     if(cv_right->is_active())
00257         ((Cell_t*)right)->m_objects<<cv_right;
00258   }
00259 }
00260 
00261 //----------
00262 
00263 TMPL  bool 
00264 Cell2dList::is_active()  {
00265     foreach (Cell* m, m_objects) 
00266     if(m->is_active()) return true;
00267   return false;
00268 }
00269 
00270 TMPL unsigned 
00271 Cell2dList::nb_intersect(void) const {
00272     unsigned sum(0);
00273     Cell2d* c;
00274     foreach (Cell* m, m_objects)
00275     { 
00276         c = dynamic_cast<Cell2d*>(m);
00277         sum+= c->nb_intersect();
00278     }
00279     return sum;
00280   }
00281 
00282 
00283 // TMPL Seq<Cell2d *> 
00284 // Cell2dList:: neighbors()
00285 //    {
00286 //     Seq<Cell2d *> r;
00287 //     Cell2d* c;
00288 //     foreach (Cell* m, m_objects)
00289 //     { 
00290 //         c = dynamic_cast<Cell2d*>(m);
00291 //         //std::cout<< c <<" has "<< c->neighbors()<<std::endl;
00292 //         r<< c->neighbors();
00293 //     }
00294 //     //std::cout<< " Total="<< r.size()<<std::endl;
00295 //   return ( r ); 
00296 //    }
00297 
00298 
00299 TMPL typename Cell2dList::Point* 
00300 Cell2dList::pair(Point * p, int &  sgn) // (!) sgn is updated inside 
00301 {
00302     if ( this->is_intersected() ) {
00303         //
00304       //std::cout<<"Reached intersection cell "<< *this<<std::endl;
00305       // std::cout<<"p= "<< *p <<std::endl;
00306       //foreach (Point*q, this->intersections() ) 
00307       //std::cout<<"q= "<< *q <<std::endl;
00308 
00309         Seq<Point*> l0,l1,l2,l3;
00310         Cell2dAlgebraicCurve* c, *v(NULL);
00311         double ev(0); int i, u(0);
00312 
00313         foreach (Cell* m, m_objects)
00314         {
00315             c = dynamic_cast<Cell2dAlgebraicCurve*>(m);
00316             int * sz = c->m_polynomial.rep().szs();
00317             int * st = c->m_polynomial.rep().str();
00318       
00319             l0<< c->s_intersections;
00320             if (c->s_intersections.member(p))
00321             {u=0; ev= (c->m_polynomial[0] >0 ? 1:-1); v=c;}
00322             l1<< c->e_intersections;
00323             if (c->e_intersections.member(p))
00324             {u=1; ev= (c->m_polynomial[(sz[0]-1)*st[0]] >0 ? 1:-1); v=c;}
00325             l2<< c->n_intersections;
00326             if (c->n_intersections.member(p))
00327             {u=2;ev=(c->m_polynomial[sz[0]*sz[1]-1]>0 ? 1:-1); v=c;}
00328             l3<< c->w_intersections;
00329             if (c->w_intersections.member(p))
00330              {u=3;ev=(c->m_polynomial[(sz[1]-1)*st[1]] >0 ? 1:-1); v=c;}
00331         }
00332 //        std::cout<<"IN: u="<<u<<", ev="<<ev<<std::endl;
00333         l0.sort(this->coord<0>);
00334         l1.sort(this->coord<1>);
00335         l2.sort(this->coord<0>);
00336         l3.sort(this->coord<1>);
00337         l0<<l1; l0<<l2.reversed(); l0<<l3.reversed();
00338         
00339         foreach (Point*q, v->intersections(u) ) 
00340          {
00341              if (q==p) break;
00342              ev*=-1;
00343          }
00344         
00345 
00346         i=l0.search(p);
00347         int a=l0.size();
00348 
00349         Point *q;
00350         if (ev*sgn>0)
00351             q=l0[(i!=0 ?i-1:a-1)];
00352         else
00353             q= l0[(i!=a-1 ?i+1:0)];
00354 
00355         //std::cout<<"res="<< *q <<std::endl;
00356 
00357         int ev2(444);
00358         foreach (Cell* m, m_objects)
00359         {
00360             c = dynamic_cast<Cell2dAlgebraicCurve*>(m);
00361             int * sz = c->m_polynomial.rep().szs();
00362             int * st = c->m_polynomial.rep().str();
00363 
00364             if (c->s_intersections.member(q))
00365             {u=0; ev2= (c->m_polynomial[0] >0 ? 1:-1); v=c;}
00366             if (c->e_intersections.member(q))
00367             {u=1; ev2= (c->m_polynomial[(sz[0]-1)*st[0]] >0 ? 1:-1); v=c;}
00368             if (c->n_intersections.member(q))
00369             {u=2;ev2=(c->m_polynomial[sz[0]*sz[1]-1]>0 ? 1:-1); v=c;}
00370             if (c->w_intersections.member(q))
00371              {u=3;ev2=(c->m_polynomial[(sz[1]-1)*st[1]] >0 ? 1:-1); v=c;}
00372         }
00373         foreach (Point*w, v->intersections(u) ) 
00374          {
00375              if (q==w) break;
00376              ev2*=-1;
00377          }
00378 
00379 //        std::cout<<"Entered from branch "<<sgn<<std::endl;
00380 
00381         if (ev*sgn>0)
00382             sgn=-ev2;
00383         else
00384             sgn=ev2;
00385 
00386 //        std::cout<<"exiting to "<<sgn<<std::endl;
00387 //        std::cout<<"OUT: u="<<u<<", ev2="<<ev2<<std::endl;
00388 
00389         return q;
00390 
00391     } else {
00392 
00393         Cell2d* c;
00394         foreach (Cell* m, m_objects)
00395         { 
00396             c = dynamic_cast<Cell2d*>(m);
00397             if ( c->intersections().member(p) )
00398                 return c->pair(p,sgn);
00399         }
00400     }
00401     std::cout<<"... Cell list pair trouble"<<std::endl;
00402     return NULL;
00403 } 
00404 
00405 TMPL typename Cell2dList::Point* 
00406 Cell2dList::starting_point( int sgn)
00407 {
00408    Cell2d* c;
00409    foreach (Cell* m, m_objects)
00410     { 
00411         if ( m->is_active() )
00412         {
00413             c = dynamic_cast<Cell2d*>(m);           
00414             return c->starting_point(sgn);
00415         }
00416     }
00417     return NULL; 
00418 }
00419 
00420 TMPL Cell2d*
00421 Cell2dList::neighbor( Point* p)
00422 {
00423     //Cell2d* cl;
00424       foreach( Cell2d *c, this->s_neighbors     )
00425         if ( c->intersections(2).member(p) )
00426           { 
00427               return c;
00428           }
00429       foreach( Cell2d *c, this->e_neighbors     )
00430         if ( c->intersections(3).member(p) )
00431           { 
00432               return c;
00433           }
00434       foreach( Cell2d *c, this->n_neighbors     )
00435         if ( c->intersections(0).member(p) )
00436           { 
00437               return c;
00438           }
00439       foreach( Cell2d *c, this->w_neighbors     )
00440         if ( c->intersections(1).member(p) )
00441           { 
00442               return c;
00443           }
00444 
00445       //std::cout<<"Point ("<<p->x()<<","<<p->y()<<") not found on neighbors of "<< this<<"("<<this->neighbors().size() <<")"<<std::endl; 
00446     return NULL;
00447 }
00448 
00449 TMPL Seq<typename mmx::shape::cell2d<C,V>::Point*>
00450 Cell2dList::intersections() const{
00451     Seq<Point *> s,e,n,w,r;
00452 
00453     Cell2d* cl;
00454     foreach (Cell* m, m_objects)
00455     {
00456         cl = dynamic_cast<Cell2d*>(m);           
00457         s<< cl->s_intersections;
00458         e<< cl->e_intersections;
00459         n<< cl->n_intersections;
00460         w<< cl->w_intersections;
00461     }
00462     s.sort(this->coord<0>);
00463     e.sort(this->coord<1>);
00464     n.sort(this->coord<0>);
00465     w.sort(this->coord<1>);
00466 
00467     r<<s;
00468     r<<e;
00469     r<<n.reversed();
00470     r<<w.reversed();
00471 
00472 
00473     return ( r ); 
00474 }
00475 
00476 
00477 } ; // namespace shape
00478 } ; // namespace mmx
00479 
00480 # undef TMPL
00481 # undef Solver
00482 # undef Cell
00483 # undef Cell2d
00484 # undef CellList
00485 # undef Cell2dList
00486 # undef AlgebraicCurve
00487 # undef Intersection2dFactory
00488 # undef Shape
00489 # endif // shape_cell2d_List_hpp