shape_doc 0.1
|
00001 /***************************************************************************** 00002 * M a t h e m a g i x 00003 ***************************************************************************** 00004 * cell2d_algebraic_curve 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_algebraic_curve_hpp 00014 # define shape_cell2d_algebraic_curve_hpp 00015 00016 # include <realroot/Interval.hpp> 00017 # include <realroot/polynomial_bernstein.hpp> 00018 # include <realroot/Seq.hpp> 00019 # include <shape/point.hpp> 00020 # include <shape/solver_implicit.hpp> 00021 # include <shape/cell2d.hpp> 00022 00023 # include <stack> 00024 # define STACK std::stack<Point*> 00025 # define TMPL template<class C, class V> 00026 # define TMPL1 template<class V> 00027 # define SELF cell2d_algebraic_curve<C,V> 00028 # define REF REF_OF(V) 00029 00030 # undef Cell_t 00031 //==================================================================== 00032 namespace mmx { 00033 namespace shape { 00034 //==================================================================== 00035 // TMPL struct cell2d_algebraic_curve; 00036 00037 // TMPL struct with_cell2d_algebraic_curve { 00038 // typedef cell2d_algebraic_curve<K> Cell2dAlgebraicCurve; 00039 // }; 00040 //-------------------------------------------------------------------- 00045 TMPL struct cell2d_subdivisor 00046 { 00047 // typedef polynomial< Interval<double>, with<Bernstein> > Polynomial; 00048 // typedef polynomial< double, with<Bernstein> > Polynomial; 00049 // typedef polynomial< mmx::GMP::rational, with<Bernstein> > Polynomial; 00050 // typedef solver_implicit<double,with_idx<double> > Solver; 00051 00052 template<class CELL> static void 00053 subdivide(CELL & cl, CELL*&, CELL*&, int v, double s); 00054 }; 00055 00056 //-------------------------------------------------------------------- 00057 TMPL 00058 template<class CELL> void 00059 cell2d_subdivisor<C,V>::subdivide(CELL& cl, CELL*& left, CELL*& right, int v, double s) { 00060 00061 typedef typename topology<C,V>::Point Point; 00062 typedef solver_implicit<C,V> Solver; 00063 00064 00065 double eps =Approximate().eps; 00066 if(v==0) {//direction v=0 00067 left = new CELL(cl); left ->set_xmax(s); 00068 right= new CELL(cl); right->set_xmin(s); 00069 00070 // left = new CELL(cl.m_polynomial, BoundingBox(cl.xmin(),s, cl.ymin(), cl.ymax(), cl.zmin(), cl.zmax())); 00071 // right= new CELL(cl.m_polynomial, BoundingBox(s,cl.xmax(), cl.ymin(), cl.ymax(), cl.zmin(), cl.zmax())); 00072 00073 tensor::split(left->m_polynomial, right->m_polynomial, v); 00074 Solver::edge_point(left->e_intersections, 00075 left->m_polynomial, Solver::east_edge, left->boundingBox()); 00076 right->w_intersections=left->e_intersections; 00077 left ->w_intersections=cl.w_intersections; 00078 right->e_intersections=cl.e_intersections; 00079 foreach(Point* p,cl.n_intersections) { 00080 if(p->x() < s) 00081 left ->n_intersections << p ; 00082 else 00083 right->n_intersections << p ; 00084 } 00085 foreach(Point* p,cl.s_intersections) { 00086 if(p->x() < s) 00087 left ->s_intersections<< p ; 00088 else 00089 right->s_intersections<< p ; 00090 } 00091 00092 foreach(Point* p,cl.m_singular) { 00093 00094 if(p->x() < s+eps) 00095 left ->m_singular << p ; 00096 // else 00097 if(p->x() > s-eps) 00098 right->m_singular << p ; 00099 } 00100 00101 /* Update neighbors */ 00102 cl.connect0(left, right); 00103 left->join0(right); 00104 00105 00106 } else {//direction v==1 00107 00108 left = new CELL(cl); left->set_ymax(s); 00109 right= new CELL(cl); right->set_ymin(s); 00110 00111 //left = new CELL(cl.m_polynomial, BoundingBox(cl.xmin(),cl.xmax(), cl.ymin(), s, cl.zmin(), cl.zmax())); 00112 //right= new CELL(cl.m_polynomial, BoundingBox(cl.xmin(),cl.xmax(), s, cl.ymax(), cl.zmin(), cl.zmax())); 00113 00114 tensor::split(left->m_polynomial, right->m_polynomial, v); 00115 Solver::edge_point(left->n_intersections, 00116 left->m_polynomial, Solver::north_edge, left->boundingBox()); 00117 right->s_intersections=left->n_intersections; 00118 left ->s_intersections=cl.s_intersections; 00119 right->n_intersections=cl.n_intersections; 00120 foreach(Point* p,cl.w_intersections) { 00121 if(p->y() < s) 00122 left ->w_intersections << p ; 00123 else 00124 right->w_intersections << p ; 00125 } 00126 00127 foreach(Point* p,cl.e_intersections) { 00128 if(p->y() < s) 00129 left ->e_intersections << p ; 00130 else 00131 right->e_intersections << p ; 00132 } 00133 00134 foreach(Point* p,cl.m_singular) { 00135 if(p->y() < s+eps) 00136 left->m_singular << p ; 00137 // else 00138 if(p->y() > s-eps) 00139 right->m_singular << p ; 00140 } 00141 00142 foreach(Point* p,cl.m_xcritical) { 00143 if(p->y() < s+eps) 00144 left->m_xcritical << p ; 00145 // else 00146 if(p->y() > s-eps) 00147 right->m_xcritical << p ; 00148 } 00149 00150 foreach(Point* p,cl.m_ycritical) { 00151 if(p->y() < s+eps) 00152 left->m_ycritical << p ; 00153 // else 00154 if(p->y() > s-eps) 00155 right->m_ycritical << p ; 00156 } 00157 00158 /* Update neighbors */ 00159 cl.connect1(left, right); 00160 left->join1(right); 00161 00162 } 00163 /* disconnect parent */ 00164 cl.disconnect( ); 00165 00166 } 00167 //==================================================================== 00168 template<class C, class V=default_env> 00169 struct cell2d_algebraic_curve : public cell2d<C,REF> { 00170 public: 00171 typedef topology<C,REF> Topology; 00172 typedef typename Topology::Point Point; 00173 // typedef typename cell2d_algebraic_curve_def<K>::Vertex Vertex; 00174 // typedef typename use<cell2d_algebraic_curve_def,V>::Vector Vector; 00175 typedef point<C,REF> Vector; 00176 typedef typename topology<C,REF>::Edge Edge; 00177 typedef cell<C,REF> Cell; 00178 typedef algebraic_set<C,REF> AlgebraicSet; 00179 typedef algebraic_curve<C,REF> AlgebraicCurve; 00180 typedef polynomial< Interval<C>, with<Bernstein> > Polynomial; 00181 typedef bounding_box<C,REF> BoundingBox; 00182 00183 typedef solver_implicit<C,V> Solver; 00184 typedef topology2d<C,V> Topology2d; 00185 00186 cell2d_algebraic_curve(const Polynomial &, const BoundingBox&, bool inter=true); 00187 cell2d_algebraic_curve(const char*, const BoundingBox&); 00188 cell2d_algebraic_curve(const typename AlgebraicSet::Polynomial& , const BoundingBox&); 00189 cell2d_algebraic_curve(AlgebraicCurve*, const BoundingBox &x); 00190 cell2d_algebraic_curve(const SELF& cl) 00191 : cell2d<C,REF>(cl.boundingBox()), m_polynomial(cl.m_polynomial) {} 00192 00193 Polynomial equation(void) { return m_polynomial; } 00194 00195 bool is_active (void) ; 00196 bool is_regular(void) ; 00197 bool is_intersected(void) {return (this->nb_intersect()>0);}; 00198 00199 virtual Point * pair(Point * p, int & sgn) ; 00200 virtual Point * starting_point( int sgn) ; 00201 00202 virtual bool insert_regular (Topology*);// = 0; 00203 virtual bool insert_singular(Topology*);// = 0; 00204 virtual void subdivide(Cell*& left, Cell*& right, int v, double s); 00205 Vector gradient(const Point& p); 00206 00207 public: 00208 Polynomial m_polynomial; 00209 Seq<Point *> m_xcritical; 00210 Seq<Point *> m_ycritical; 00211 // AlgebraicCurve* m_shape; 00212 }; 00213 00214 //==================================================================== 00215 TMPL inline void 00216 print(SELF* cv) { 00217 typedef typename SELF::Point Point; 00218 std::cout << "point(s) b: "; 00219 foreach(Point* p, cv->n_intersections) 00220 std::cout <<" ["<<p->x()<<" "<<p->y()<<"]"; 00221 foreach(Point* p, cv->s_intersections) 00222 std::cout <<" ["<<p->x()<<" "<<p->y()<<"]"; 00223 foreach(Point* p, cv->w_intersections) 00224 std::cout <<" ["<<p->x()<<" "<<p->y()<<"]"; 00225 foreach(Point* p, cv->e_intersections) 00226 std::cout <<" ["<<p->x()<<" "<<p->y()<<"]"; 00227 std::cout<<std::endl; 00228 00229 std::cout << "Point(s) s: "; 00230 foreach(Point* p, cv->m_singular) 00231 std::cout <<" ["<<p->x()<<" "<<p->y()<<"]"; 00232 std::cout<<std::endl; 00233 } 00234 //-------------------------------------------------------------------- 00235 TMPL 00236 SELF::cell2d_algebraic_curve(const Polynomial& pol, const BoundingBox& bx, bool inter): cell2d<C,REF>(bx), m_polynomial(pol) 00237 { 00238 //std::cout<<"Alegbraic cell: "<<bx<<std::endl; 00239 00240 if (inter) 00241 { 00242 //std::cout<<"compute inter "<<bx<<std::endl; 00243 Solver::edge_point(this->n_intersections, m_polynomial, Solver::north_edge, bx); 00244 Solver::edge_point(this->s_intersections, m_polynomial, Solver::south_edge, bx); 00245 Solver::edge_point(this->w_intersections, m_polynomial, Solver::west_edge , bx); 00246 Solver::edge_point(this->e_intersections, m_polynomial, Solver::east_edge , bx); 00247 } 00248 //Solver::extremal(this->m_singular, m_polynomial, bx); 00249 00250 } 00251 //-------------------------------------------------------------------- 00252 TMPL 00253 SELF::cell2d_algebraic_curve(const typename AlgebraicSet::Polynomial& p, const BoundingBox & b): cell2d<C,REF>(b) 00254 { 00255 //std::cout<<"Alegbraic cell: "<<p<<std::endl; 00256 Seq<mmx::GMP::rational> bx; 00257 bx<<as<mmx::GMP::rational>(b.xmin()); 00258 bx<<as<mmx::GMP::rational>(b.xmax()); 00259 bx<<as<mmx::GMP::rational>(b.ymin()); 00260 bx<<as<mmx::GMP::rational>(b.ymax()); 00261 00262 tensor::bernstein<mmx::GMP::rational> polq(p.rep(),bx); 00263 00264 let::assign(m_polynomial.rep(),polq); 00265 00266 Solver::edge_point(this->n_intersections, m_polynomial, Solver::north_edge, b); 00267 Solver::edge_point(this->s_intersections, m_polynomial, Solver::south_edge, b); 00268 Solver::edge_point(this->w_intersections, m_polynomial, Solver::west_edge , b); 00269 Solver::edge_point(this->e_intersections, m_polynomial, Solver::east_edge , b); 00270 00271 Solver::extremal(this->m_singular, p, b); 00272 00273 // foreach(Point* p,this-> s_intersections) 00274 // std::cout<<"s_ boundary point: "<<p->x()<<", "<<p->y() <<std::endl; 00275 // foreach(Point* p,this-> e_intersections) 00276 // std::cout<<"e_ boundary point: "<<p->x()<<", "<<p->y() <<std::endl; 00277 // foreach(Point* p,this-> n_intersections) 00278 // std::cout<<"n_ boundary point: "<<p->x()<<", "<<p->y() <<std::endl; 00279 // foreach(Point* p,this-> w_intersections) 00280 // std::cout<<"w_ boundary point: "<<p->x()<<", "<<p->y() <<std::endl; 00281 00282 // foreach(Point* p,this-> m_singular) 00283 // std::cout<<"extremal point: "<<p->x()<<", "<<p->y() <<std::endl; 00284 00285 //std::cout<<"Found "<<this->nb_intersect()<<" boundary and "<<this->m_singular.size()<<" extremal points" <<std::endl; 00286 } 00287 //-------------------------------------------------------------------- 00288 TMPL 00289 SELF::cell2d_algebraic_curve(const char* s, const BoundingBox & b): cell2d<C,REF>(b) 00290 { 00291 Seq<mmx::GMP::rational> bx; 00292 bx<<as<mmx::GMP::rational>(b.xmin()); 00293 bx<<as<mmx::GMP::rational>(b.xmax()); 00294 bx<<as<mmx::GMP::rational>(b.ymin()); 00295 bx<<as<mmx::GMP::rational>(b.ymax()); 00296 00297 typename AlgebraicSet::Polynomial pol(s); 00298 tensor::bernstein<mmx::GMP::rational> polq(s,bx); 00299 00300 let::assign(m_polynomial.rep(),polq); 00301 00302 Solver::edge_point(this->n_intersections, m_polynomial, Solver::north_edge, b); 00303 Solver::edge_point(this->s_intersections, m_polynomial, Solver::south_edge, b); 00304 Solver::edge_point(this->w_intersections, m_polynomial, Solver::west_edge , b); 00305 Solver::edge_point(this->e_intersections, m_polynomial, Solver::east_edge , b); 00306 00307 Solver::extremal(this->m_singular, pol, b); 00308 foreach(Point* p,this-> m_singular) 00309 std::cout<<"**extremal point: "<<p->x()<<" "<<p->y() <<std::endl; 00310 } 00311 //-------------------------------------------------------------------- 00312 TMPL 00313 SELF::cell2d_algebraic_curve(AlgebraicCurve* cv, const BoundingBox & b) 00314 { 00315 new (this) SELF(cv->equation(),b ); 00316 } 00317 //-------------------------------------------------------------------- 00318 TMPL bool 00319 SELF::is_regular() { 00320 // Assumption: cells with extremal points (dx=dy=0) that do not belong on the curve do not intersect the curve (assumes deep enough subdivision) 00321 00322 if(this->m_singular.size()>1) return false; 00323 00324 // if (0) 00325 if (this->m_singular.size()==0) { 00326 if(!has_sign_variation(m_polynomial)) return true; 00327 00328 Polynomial dx= diff(m_polynomial,0); 00329 if(!has_sign_variation(dx)) return true; 00330 00331 Polynomial dy= diff(m_polynomial,1); 00332 if(!has_sign_variation(dy)) return true; 00333 00334 int n= this->nb_intersect(); 00335 return ( n==2 ); 00336 //return ( n%2==0); 00337 //return (n == 4 || n == 2 || n == 0 ); 00338 } 00339 00340 //return true; 00341 00342 //-------------------------------------------------------------------- 00343 if(this->m_singular.size()==1) { 00344 // Polynomial 00345 // dxf = diff(m_polynomial,0), 00346 // dyf = diff(m_polynomial,1); 00347 // std::cout<< "__________________"<<std::endl; 00348 // std::cout<< m_polynomial;std::cout<< std::endl; 00349 // std::cout<< "__________________"<<std::endl; 00350 // std::cout<< dxf;std::cout<< std::endl; 00351 // std::cout<< "__________________"<<std::endl; 00352 // std::cout<< dyf;std::cout<< std::endl; 00353 // std::cout<< "__________________"<<std::endl; 00354 00355 // int d; 00356 // d = 1-2*topological_degree(dxf,dyf); 00357 // d = 0; 00358 return false; //(d==ni); 00359 } 00360 00361 return true; 00362 } 00363 //-------------------------------------------------------------------- 00364 TMPL bool 00365 SELF::is_active() { 00366 00367 return (has_sign_variation(this->m_polynomial)); 00368 00369 // if(this->m_singular.size()>0) 00370 // return true; 00371 // return (this->nb_intersect()>0); 00372 } 00373 //-------------------------------------------------------------------- 00374 TMPL bool 00375 SELF::insert_regular(Topology* t) { 00376 Topology2d* s= dynamic_cast<Topology2d*>(t); 00377 Seq<Point*> l; 00378 int ni, sgn(1); 00379 Point *p,*q; 00380 l= this->intersections(); 00381 ni=l.size(); 00382 00383 std::cout<<"alg. curve, inserting regular "<< *this <<std::endl; 00384 foreach( Point* e, l) 00385 std::cout<<"("<< e->x()<<", "<<e->y()<<")"<<std::endl; 00386 00387 //assert(ni%2==0); 00388 00389 if(this->m_singular.size()==0) 00390 { 00391 foreach(Point* v, l) 00392 s->insert(v); 00393 00394 00395 while (l.size()>0) 00396 { 00397 //std::cout<<"L = "<< l <<std::endl; 00398 p= l[0]; 00399 q= this->pair(p,sgn); 00400 l.erase(0); 00401 //std::cout<<"erased "<< p <<" "<<std::endl;int k=l.search(q); 00402 l.erase( l.search(q) ); 00403 //std::cout<<"erased "<< q <<" ~"<<k<<std::endl; 00404 s->insert(p,q); 00405 //std::cout<<"edge "<<0<<" "<<q<<std::endl; 00406 //std::cout<<"l.size()="<<l.size() <<std::endl; 00407 } 00408 } 00409 else 00410 { 00411 //std::cout<<"Singular:"<<std::endl; 00412 //std::cout<<this<<std::endl; 00413 t->insert((BoundingBox*)this,false); 00414 00415 Point *c=this->m_singular[0]; 00416 s->m_specials<<c; 00417 s->insert(c); 00418 foreach(Point* p, this->n_intersections) s->insert(new Edge(p,c)); 00419 foreach(Point* p, this->e_intersections) s->insert(new Edge(p,c)); 00420 foreach(Point* p, this->s_intersections) s->insert(new Edge(p,c)); 00421 foreach(Point* p, this->w_intersections) s->insert(new Edge(p,c)); 00422 } 00423 00424 //std::cout<<"ok "<<std::endl; 00425 00426 return true; 00427 00428 } 00429 //-------------------------------------------------------------------- 00430 TMPL bool 00431 SELF::insert_singular(Topology* t) { 00432 00433 // std::cout<<"Singular!!"<<std::endl; 00434 00435 //Mark singular box with a cross 00436 //t->insert((BoundingBox*)this,true);return true; 00437 00438 Topology2d* s = dynamic_cast<Topology2d*>(t); 00439 int sgn(1); 00440 00441 Seq<Point*> l; 00442 foreach(Point* p, this->n_intersections) { 00443 s->insert(p); l<<p; 00444 } 00445 foreach(Point* p, this->e_intersections) { 00446 s->insert(p); l<<p; 00447 } 00448 foreach(Point* p, this->s_intersections) { 00449 s->insert(p); l<<p; 00450 } 00451 foreach(Point* p, this->w_intersections) { 00452 s->insert(p); l<<p; 00453 } 00454 int ni=l.size(); 00455 00456 if(this->m_singular.size()==1) { 00457 00458 //std::cout<<"Singular:"<<std::endl; 00459 //std::cout<<this<<std::endl; 00460 //t->insert((BoundingBox*)this,false); 00461 00462 00463 Point *c=this->m_singular[0]; 00464 s->m_specials<<c; 00465 s->insert(c); 00466 foreach(Point* p, this->n_intersections) s->insert(new Edge(p,c)); 00467 foreach(Point* p, this->e_intersections) s->insert(new Edge(p,c)); 00468 foreach(Point* p, this->s_intersections) s->insert(new Edge(p,c)); 00469 foreach(Point* p, this->w_intersections) s->insert(new Edge(p,c)); 00470 return true; 00471 } 00472 else // no singular points in the cell 00473 { 00474 if(ni==2) { // 2 points on the boundary 00475 s->insert(l[0],l[1]); 00476 return true; 00477 } 00478 else // more than one branch in the cell 00479 { 00480 Point *p,*q; 00481 while (l.size()>0) 00482 { 00483 p= l[0]; 00484 q= this->pair(p,sgn); 00485 l.erase(0); 00486 l.erase( l.search(q) ); 00487 s->insert(p,q); 00488 } 00489 } 00490 } 00491 00492 //std::cout<<"singular cell with "<<ni<<" bpts "<<this->m_singular.size()<<" epts"<<std::endl; 00493 00494 return true; 00495 } 00496 00497 //-------------------------------------------------------------------- 00498 TMPL void 00499 SELF::subdivide(Cell*& Left, Cell*& Right, int v, double s) { 00500 cell2d_subdivisor<C,V>::subdivide( *this,(SELF*&)Left,(SELF*&)Right,v,s); 00501 } 00502 //-------------------------------------------------------------------- 00503 TMPL typename SELF::Vector 00504 SELF::gradient(const Point& p) { 00505 Polynomial 00506 dx= diff(m_polynomial,0), 00507 dy= diff(m_polynomial,1); 00508 double 00509 u0= (p[0]-this->xmin())/(this->xmax()-this->xmin()), 00510 u1= (p[1]-this->ymin())/(this->ymax()-this->ymin()); 00511 Vector v; 00512 v[0] = dx(u0,u1); 00513 v[1] = dy(u0,u1); 00514 return v; 00515 } 00516 00517 //-------------------------------------------------------------------- 00518 TMPL typename SELF::Point* 00519 SELF::starting_point(int sgn) { 00520 00521 // std::cout<<"startingPoint.AlgCurve"<<std::endl; 00522 00523 Seq<Point*> l, all; 00524 unsigned a; 00525 all = this->intersections(); 00526 00527 // std::cout<<this<<" , "<<a<<std::endl; 00528 // foreach(Point*p,all) 00529 // std::cout<<p->x()<<" "<<p->y()<<" "<<p->z()<<std::endl; 00530 00531 00532 // if (l.size()==4) // two duplicate corners 00533 // { 00534 // all<< l[1]; 00535 // all<< l[0]; 00536 // } 00537 // else 00538 // all=l; 00539 00540 00541 a = all.size(); 00542 if (a==1) return all[0]; 00543 00544 int ev(0); 00545 int u ;//position of p 00546 unsigned 00547 s=this->s_intersections.size() ,// ~0 00548 e=this->e_intersections.size() ,// ~1 00549 //n=this->n_intersections.size() ,// ~2 00550 w=this->w_intersections.size() ;// ~3 00551 00552 u= ( 0<s ? 0 : 00553 ( 0<s+e ? 1 : 00554 ( 0<a-w ? 2 : 00555 3 ))); 00556 00557 int * sz = this->m_polynomial.rep().szs(); 00558 int * st = this->m_polynomial.rep().str(); 00559 00560 switch (u){ 00561 case 0: 00562 ev= (this->m_polynomial[0] >0 ? 1:-1); 00563 break; 00564 case 1: 00565 ev= (this->m_polynomial[(sz[0]-1)*st[0]] >0 ? 1:-1); 00566 break; 00567 case 2: 00568 ev= (this->m_polynomial[sz[0]*sz[1]-1]>0 ? 1:-1); 00569 break; 00570 case 3: 00571 ev= (this->m_polynomial[(sz[1]-1)*st[1]] >0 ? 1:-1); 00572 break; 00573 } 00574 00575 if (ev*sgn>0) { 00576 return all[0]; 00577 } 00578 else { 00579 return all[1]; 00580 } 00581 } 00582 00583 //-------------------------------------------------------------------- 00584 TMPL typename SELF::Point* 00585 SELF::pair( typename SELF::Point* p, int & sgn) { 00586 // Pair: returns a neighboring point on the component (p,sgn) 00587 // The candidates are the 2 neighbor intersections of p in *this 00588 00589 Seq<Point*> all; 00590 int a; 00591 all= this->intersections(); 00592 a = all.size(); 00593 if (a==2)// regular cell with a single branch 00594 { return (all[0]==p ? all[1]: all[0]); } 00595 if (a==1) 00596 { std::cout<<"Only 1 intersection point in "<< *this <<" (i.e."<<*all[0] <<")"<<std::endl; 00597 00598 // if ( abs( l[0]->x()-this->xmin()<EPSILON) && 00599 // abs( l[0]->y()-this->ymin()<EPSILON) ) 00600 00601 00602 return (p); } 00603 00604 00605 int 00606 s=this->s_intersections.size() ,// ~0 00607 e=this->e_intersections.size() ,// ~1 00608 //n=this->n_intersections.size() ,// ~2 00609 w=this->w_intersections.size() ;// ~3 00610 int j,k,i= all.search(p); 00611 00612 //if (this->is_regular() ) { 00613 if (this->m_singular.size()==0 ) { 00614 00615 00616 Vector grq, grp = this->gradient(*p); 00617 foreach(Point* q, all) 00618 if ( q != p) 00619 { 00620 grq = this->gradient(*q); 00621 if(grp[0]*grq[0]>0 && grp[1]*grq[1]>0 ) 00622 return (q); 00623 } 00624 00625 //box has 2 or more "identical" branches 00626 00627 //p is part of critical branch 00628 00629 std::cout<<"...maybe pair Trouble"<< this<<std::endl; 00630 00631 for (int v=0;v<a;v++) 00632 for (int w=v+1;w<a;v++) 00633 { 00634 grp= this->gradient(*all[v]); 00635 grq= this->gradient(*all[w]); 00636 if( grp[0]*grq[0]>0 && grp[1]*grq[1]>0 ) 00637 { 00638 for (int u=0; u<a;u++) 00639 if ( u!=v && u!=w && all[u]!=p ) 00640 return (all[u]); 00641 } 00642 } 00643 00644 std::cout<<"empty BOX:("<<this->m_singular.size()<<",a="<<a<<")"<<this <<std::endl; 00645 foreach(Point*v,all) { 00646 Vector gr= this->gradient(*v); 00647 //std::cout<<"("<<v->x()<<","<<v->y()<<"): "; 00648 std::cout<<(gr[0]>0?1:-1)<<","<<(gr[1]>0?1:-1) <<std::endl; 00649 } 00650 00651 //look non-tangent direction 00652 foreach(Point* q, all) 00653 if ( q != p) 00654 { 00655 grq = this->gradient(*q); 00656 if( abs(grp[0]) < 0.017) 00657 { if (grp[1]*grq[1]>0) 00658 return (q); 00659 } 00660 else if ( abs(grp[1])< 0.01) 00661 { if (grp[0]*grq[0]>0) 00662 return (q); 00663 } 00664 } 00665 00666 std::cout<<"...pair Trouble"<< this<<std::endl; 00667 00668 00669 00670 // foreach(Point* q, all) 00671 // if ( q != p) 00672 // { 00673 return (all[0]); 00674 // } 00675 } 00676 else {//singular box 00677 00678 //std::cout<< "SBOX: " <<this <<std::endl; 00679 //std::cout<< " " <<all <<std::endl; 00680 //for (unsigned y=0;y<4;y++) 00681 //std::cout<<y <<": ("<<all[y]->x()<<","<<all[y]->y()<<")"<<std::endl; 00682 00683 // Cell with 1 self-intersection 00684 int ev(0); 00685 int u, v;//side of p, ln resp. 00686 j= ( i!=0 ? i-1 : a-1 ); 00687 k= ( i!=a-1 ? i+1 : 0 ); 00688 00689 //std::cout<<"j,i,k (left,p,right)="<<j <<" "<<i << " "<<k<< std::endl; 00690 00691 Point *ln= all[j], 00692 *rn= all[k] ; 00693 00694 //std::cout<<"i= "<< i<<", j=" <<j<< std::endl; 00695 // std::cout<<"("<<a<<")"<<s<<", "<<e<<", "<<n<<", "<<w<< std::endl; 00696 00697 u= ( i<s ? 0 : 00698 ( i<s+e ? 1 : 00699 ( i<a-w ? 2 : 00700 3 ))); 00701 v= ( j<s ? 0 : 00702 ( j<s+e ? 1 : 00703 ( j<a-w ? 2 : 00704 3 ))); 00705 00706 int * sz = this->m_polynomial.rep().szs(); 00707 int * st = this->m_polynomial.rep().str(); 00708 00709 switch (u){ 00710 case 0: 00711 ev= (this->m_polynomial[0] >0 ? 1:-1); 00712 if (v==0 && j%2==0) // p, ln on the same face 00713 ev*=-1; 00714 break; 00715 case 1: 00716 ev= (this->m_polynomial[(sz[0]-1)*st[0]] >0 ? 1:-1); 00717 if (v==1 && (j-s)%2==0) // p, ln on the same face 00718 ev*=-1; 00719 break; 00720 case 2: 00721 ev= (this->m_polynomial[sz[0]*sz[1]-1]>0 ? 1:-1); 00722 if (v==2 && (j-s-e)%2==0) // p, ln on the same face 00723 ev*=-1; 00724 break; 00725 case 3: 00726 ev= (this->m_polynomial[(sz[1]-1)*st[1]] >0 ? 1:-1); 00727 if (v==3 && (j-a+w)%2==0) // p, ln on the same face 00728 ev*=-1; 00729 break; 00730 } 00731 00732 // std::cout<<"Cell"<<this <<"("<<(sgn==1 ? "+": "-")<<")" <<std::endl; 00733 // std::cout<<"u= "<< u<<", v=" <<v<<", ev=" <<ev << std::endl; 00734 // std::cout<<"ln= "<< ln->x()<<","<<ln->y() << std::endl; 00735 // std::cout<<"p = "<< p->x()<<","<<p->y() << std::endl; 00736 // std::cout<<"rn= "<< rn->x()<<","<<rn->y() << std::endl; 00737 // if (ev*sgn>0) std::cout<<"result is ln"<< std::endl; 00738 // else std::cout<<"result is rn"<< std::endl; 00739 00740 00741 00742 if (ev*sgn>0) return ln; 00743 else return rn; 00744 } 00745 } 00746 00747 //==================================================================== 00748 } ; // namespace shape 00749 } ; // namespace mmx 00750 # undef Solver 00751 # undef SELF 00752 # undef REF 00753 # undef TMPL 00754 # undef STACK 00755 # endif // shape_cell2d_algebraic_curve_hpp