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