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