00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 # ifndef shape_bcell2d_List_hpp
00014 # define shape_bcell2d_List_hpp
00015
00016 # include <shape/topology.hpp>
00017 # include <shape/bcell_list.hpp>
00018 # include <shape/bcell2d_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 bcell2d_algebraic_curve<C,V>
00024 # define Intersection2dFactory intersection2d_factory<C,V>
00025 # define Solver solver_implicit<C,V>
00026
00027 # define Cell bcell<C,V>
00028 # define Cell2d bcell2d<C,V>
00029 # define CellList bcell_list<C,V>
00030 # define Cell2dList bcell2d_list<C,V>
00031 namespace mmx {
00032 namespace shape {
00033
00034
00035 TMPL
00036 class bcell2d_list: public bcell2d<C,V> {
00037 public:
00038 typedef typename Cell::BoundingBox BoundingBox;
00039 typedef typename bcell2d<C,V>::Point Point;
00040 typedef topology<C,V> Topology;
00041
00042 bcell2d_list(void) ;
00043 bcell2d_list(double xmin, double xmax) ;
00044 bcell2d_list(double xmin, double xmax, double ymin, double ymax) ;
00045 bcell2d_list(double xmin, double xmax, double ymin, double ymax, bool itr) ;
00046 bcell2d_list(const BoundingBox& bx);
00047 virtual ~bcell2d_list(void) ;
00048
00049 virtual bool is_regular (void) ;
00050 virtual bool is_active (void) ;
00051 virtual bool is_intersected(void) ;
00052
00053 virtual bool insert_regular(Topology*);
00054 virtual bool insert_singular(Topology*);
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
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
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 bcell2d<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::bcell2d_list(void): m_intersected(false) {}
00141
00142 TMPL
00143 Cell2dList::bcell2d_list(double xmin, double xmax, double ymin, double ymax) : bcell2d<C,V>(xmin, xmax, ymin, ymax), m_intersected(false) {}
00144
00145 TMPL
00146 Cell2dList::bcell2d_list(double xmin, double xmax, double ymin, double ymax, bool itr) : bcell2d<C,V>(xmin, xmax, ymin, ymax), m_intersected(itr) {}
00147
00148 TMPL
00149 Cell2dList::bcell2d_list(const BoundingBox& bx): bcell2d<C,V>(bx), m_intersected(false) {};
00150
00151 TMPL
00152 Cell2dList::~bcell2d_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
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
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
00228 this->connect1( (Cell_t*)left, (Cell_t*)right);
00229 ((Cell_t*)left)->join1((Cell_t*)right);
00230
00231 } else {
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
00243 this->connect0((Cell_t*)left, (Cell_t*)right);
00244 ((Cell_t*)left)->join0((Cell_t*)right);
00245
00246 }
00247
00248
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
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 TMPL typename Cell2dList::Point*
00300 Cell2dList::pair(Point * p, int & sgn)
00301 {
00302 if ( this->is_intersected() ) {
00303
00304
00305
00306
00307
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
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
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
00380
00381 if (ev*sgn>0)
00382 sgn=-ev2;
00383 else
00384 sgn=ev2;
00385
00386
00387
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
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
00446 return NULL;
00447 }
00448
00449 TMPL Seq<typename mmx::shape::bcell2d<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 } ;
00478 } ;
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