shape_doc 0.1
|
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