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_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