shape_doc 0.1
|
00001 /***************************************************************************** 00002 * M a t h e m a g i x 00003 ***************************************************************************** 00004 * Cell3d for Algebraic Curve 00005 * 2008-03-20 00006 * Bernard Mourrain & Julien Wintz 00007 ***************************************************************************** 00008 * Copyright (C) 2008 INRIA Sophia-Antipolis 00009 ***************************************************************************** 00010 * Comments : 00011 ****************************************************************************/ 00012 00013 # ifndef shape_cell3d_algebraic_curve_hpp 00014 # define shape_cell3d_algebraic_curve_hpp 00015 00016 # include <realroot/Interval.hpp> 00017 # include <realroot/polynomial_bernstein.hpp> 00018 # include <realroot/Seq.hpp> 00019 # include <shape/cell3d.hpp> 00020 # include <shape/box_face.hpp> 00021 # include <shape/topology.hpp> 00022 # include <shape/algebraic_curve.hpp> 00023 # include <shape/solver_implicit.hpp> 00024 00025 # define TMPL template<class C, class V> 00026 # define AlgebraicCurve algebraic_curve<C,V> 00027 # define SELF cell3d_algebraic_curve<C,V> 00028 00029 //==================================================================== 00030 namespace mmx { namespace shape { 00031 //==================================================================== 00032 00033 template<class C, class V= default_env> 00034 struct cell3d_algebraic_curve : public cell3d<C,V> { 00035 public: 00036 00037 typedef topology<C,V> Topology; 00038 typedef tpl3d<C,V> Topology3d; 00039 typedef vertex<C,V> Point; 00040 00041 typedef polynomial< double, with<Bernstein> > Polynomial; 00042 00043 typedef cell3d<C,V> Cell; 00044 typedef cell3d<C,V> Cell3d; 00045 typedef typename Cell3d::BoundingBox BoundingBox; 00046 00047 typedef solver_implicit<C,V> Solver; 00048 00049 cell3d_algebraic_curve(const SELF&); 00050 cell3d_algebraic_curve(const Seq<Polynomial>&, const BoundingBox& ); 00051 cell3d_algebraic_curve(AlgebraicCurve *, const BoundingBox& bx); 00052 00053 bool is_regular(void); 00054 bool is_active (void) const; 00055 00056 virtual bool is_intersected (void) {return true;} 00057 00058 template<class TOPOLOGY> 00059 bool inserted_regular_in(TOPOLOGY*) ; 00060 00061 template<class TOPOLOGY> 00062 bool inserted_singular_in(TOPOLOGY*) ; 00063 00064 virtual bool insert_regular (Topology*) ; 00065 virtual bool insert_singular(Topology*) ; 00066 00067 virtual void polygonise (Topology3d*) {}; 00068 00069 virtual int subdivide(SELF*& left, SELF*& right) ; 00070 virtual void subdivide(Cell*& left, Cell*& right, int v, double s); 00071 00072 int nbeq() const { return m_polynomials.size(); } 00073 Polynomial equation(int i=0) const { return m_polynomials[i]; } 00074 00075 struct along { 00076 int m_dir; 00077 along(int i):m_dir(i) {} 00078 bool operator()(Point *p1, Point* p2) { 00079 return (*p1)[m_dir]<(*p2)[m_dir]; 00080 } 00081 }; 00082 00083 bool topology_regular(Topology*) { return true;} 00084 // void check_cluster(Seq<Point*>& , double eps=0.00001); 00085 void check_insert (Point*, Seq<Point*>& , double eps=0.00001); 00086 00087 public: 00088 Seq<Polynomial> m_polynomials; 00089 AlgebraicCurve* m_shape; 00090 int m_reg; 00091 }; 00092 00093 //==================================================================== 00094 TMPL 00095 SELF::cell3d_algebraic_curve(const SELF& c): 00096 m_polynomials(c.m_polynomials), m_shape(c.m_shape), m_reg(-1) {}; 00097 00098 TMPL 00099 SELF::cell3d_algebraic_curve(const Seq<Polynomial>& s, const BoundingBox& b): 00100 Cell3d(b), m_polynomials(s), m_reg(-1) 00101 { 00102 00103 } 00104 00105 TMPL 00106 SELF::cell3d_algebraic_curve(AlgebraicCurve* cv, const BoundingBox& b): Cell3d(b), m_reg(-1) { 00107 Seq<mmx::GMP::rational> bx; 00108 bx<<as<mmx::GMP::rational>(b.xmin()); 00109 bx<<as<mmx::GMP::rational>(b.xmax()); 00110 bx<<as<mmx::GMP::rational>(b.ymin()); 00111 bx<<as<mmx::GMP::rational>(b.ymax()); 00112 bx<<as<mmx::GMP::rational>(b.zmin()); 00113 bx<<as<mmx::GMP::rational>(b.zmax()); 00114 00115 Polynomial tmp; 00116 for(int i=0;i<cv->nbequation();i++) { 00117 tensor::bernstein<mmx::GMP::rational> polq(cv->equation(i).rep(),bx); 00118 let::assign(tmp.rep(),polq); 00119 m_polynomials<<tmp; 00120 } 00121 00122 Solver::face_point(this->m_boundary, m_polynomials, Solver::north_face, b); 00123 Solver::face_point(this->m_boundary, m_polynomials, Solver::south_face, b); 00124 Solver::face_point(this->m_boundary, m_polynomials, Solver::west_face , b); 00125 Solver::face_point(this->m_boundary, m_polynomials, Solver::east_face , b); 00126 Solver::face_point(this->m_boundary, m_polynomials, Solver::front_face, b); 00127 Solver::face_point(this->m_boundary, m_polynomials, Solver::back_face , b); 00128 00129 foreach(Point* p, this->m_boundary) std::cout<<"n "<<p->x()<<" "<<p->y()<<" "<<p->z() <<std::endl; 00130 00131 // check_cluster(this->m_boundary); 00132 // Solver::singular(m_singular, m_polynomial, b); 00133 } 00134 00135 TMPL bool 00136 SELF::is_active() const { 00137 // std::cout<<"Is active "<<m_polynomials[0].rep()<<std::endl; 00138 00139 if(!has_sign_variation(m_polynomials[0])) 00140 return false; 00141 00142 // std::cout<<"Is active "<<m_polynomials[1]<<std::endl; 00143 00144 if(!has_sign_variation(m_polynomials[1])) 00145 //m_polynomials[1].begin(),m_polynomials[1].end())) 00146 return false; 00147 00148 // std::cout<<"Is active end"<<std::endl; 00149 00150 return true; 00151 } 00152 00153 TMPL bool 00154 SELF::is_regular() { 00155 if(this->m_singular.size()>1) return false; 00156 00157 Polynomial 00158 tx=diff(equation(0),1)*diff(equation(1),2)-diff(equation(1),1)*diff(equation(0),2); 00159 if(!has_sign_variation(tx)) 00160 { m_reg=0; return true; } 00161 00162 Polynomial 00163 ty=diff(equation(0),0)*diff(equation(1),2)-diff(equation(1),0)*diff(equation(0),2); 00164 if(!has_sign_variation(ty)) 00165 { m_reg=1; return true; } 00166 00167 Polynomial 00168 tz=diff(equation(0),0)*diff(equation(1),1)-diff(equation(1),0)*diff(equation(0),1); 00169 if(!has_sign_variation(tz)) 00170 { m_reg=2; return true; } 00171 00172 // int n=this->m_boundary.size(); 00173 // if(n > 2) 00174 return false; 00175 // else { 00176 // return true; 00177 // } 00178 } 00179 //-------------------------------------------------------------------- 00180 TMPL int 00181 SELF::subdivide(SELF*& Left, SELF*& Right) { 00182 int v; double s; 00183 this->split_position(v,s); 00184 this->subdivide((Cell*&)Left,(Cell*&)Right,v,s); 00185 return v; 00186 } 00187 //-------------------------------------------------------------------- 00188 TMPL void 00189 SELF::subdivide(Cell*& Left, Cell*& Right, int v, double c) { 00190 00191 SELF * left, * right; 00192 // if (this->m_boundary.size()>2){ 00193 // std::cout<<" split cell with "<<this->m_boundary.size()<<" points"<<std::endl; 00194 // foreach(Point* p, this->m_boundary) 00195 // std::cout<<" "<<p->x()<<" "<<p->y()<<" "<<p->z()<<std::endl; 00196 // } 00197 if(v==0){ 00198 c=(this->xmin()+this->xmax())/2; 00199 left = new SELF(m_polynomials, BoundingBox(this->xmin(),c, this->ymin(),this->ymax(), this->zmin(),this->zmax())); 00200 right= new SELF(m_polynomials, BoundingBox(c,this->xmax(), this->ymin(),this->ymax(), this->zmin(),this->zmax())); 00201 } else if(v==1) { 00202 c=(this->ymin()+this->ymax())/2; 00203 left = new SELF(m_polynomials, BoundingBox(this->xmin(),this->xmax(), this->ymin(),c, this->zmin(),this->zmax())); 00204 right= new SELF(m_polynomials, BoundingBox(this->xmin(),this->xmax(), c,this->ymax(), this->zmin(),this->zmax())); 00205 } else { 00206 c=(this->zmin()+this->zmax())/2; 00207 left = new SELF(m_polynomials, BoundingBox(this->xmin(),this->xmax(), this->ymin(),this->ymax(), this->zmin(),c)); 00208 right= new SELF(m_polynomials, BoundingBox(this->xmin(),this->xmax(), this->ymin(),this->ymax(), c,this->zmax())); 00209 } 00210 00211 for(int i=0;i<nbeq();i++) { 00212 tensor::split(left->m_polynomials[i], right->m_polynomials[i], v); 00213 } 00214 00215 if(v==0) { 00216 foreach(Point* p, this->m_boundary) { 00217 if (Solver::east_face.is_valid(*p,left->boundingBox())) 00218 left->m_boundary << p ; 00219 if (Solver::west_face.is_valid(*p,right->boundingBox())) 00220 right->m_boundary << p ; 00221 } 00222 } else if (v==1) { 00223 foreach(Point* p, this->m_boundary) { 00224 if (Solver::north_face.is_valid(*p,left->boundingBox())) 00225 left->m_boundary << p ; 00226 if (Solver::south_face.is_valid(*p,right->boundingBox())) 00227 right->m_boundary << p ; 00228 } 00229 } else { 00230 foreach(Point* p, this->m_boundary) { 00231 if (Solver::front_face.is_valid(*p,left->boundingBox())) 00232 left->m_boundary << p ; 00233 if (Solver::back_face.is_valid(*p,right->boundingBox())) 00234 right->m_boundary << p ; 00235 } 00236 } 00237 00238 00239 00240 Seq<Point*> tmp; 00241 // Points on vertical faces of back subcells 00242 if(v==0){ 00243 Solver::face_point(tmp, left->m_polynomials, Solver::east_face, left->boundingBox()); 00244 foreach(Point *p, tmp){ 00245 check_insert(p, left->m_boundary); 00246 check_insert(p, right->m_boundary); 00247 } 00248 } else if(v==1) { 00249 Solver::face_point(tmp, left->m_polynomials, Solver::north_face, left->boundingBox()); 00250 foreach(Point *p, tmp){ 00251 check_insert(p, left->m_boundary); 00252 check_insert(p, right->m_boundary); 00253 } 00254 } else { 00255 Solver::face_point(tmp, left->m_polynomials, Solver::front_face, left->boundingBox()); 00256 foreach(Point *p, tmp){ 00257 check_insert(p, left->m_boundary); 00258 check_insert(p, right->m_boundary); 00259 } 00260 } 00261 // if (tmp.size()>0){ 00262 // std::cout<<" insert "<<tmp.size()<<" points"<<std::endl; 00263 // foreach(Point* p, tmp) 00264 // std::cout<<" "<<p->x()<<" "<<p->y()<<" "<<p->z()<<std::endl; 00265 // } 00266 // if (left->m_boundary.size()>2){ 00267 // std::cout<<"["<<left->xmin()<<" "<<left->xmax()<<" "<<left->ymin()<<" "<<left->ymax()<<" "<<left->zmin()<<" "<<left->zmax()<<"]"<<std::endl; 00268 // std::cout<<" left cell with "<<left->m_boundary.size()<<" points"<<std::endl; 00269 // foreach(Point* p, left->m_boundary) 00270 // std::cout<<" "<<p->x()<<" "<<p->y()<<" "<<p->z()<<std::endl; 00271 // } 00272 // if (right->m_boundary.size()>2){ 00273 // std::cout<<" right cell with "<<right->m_boundary.size()<<" points"<<std::endl; 00274 // std::cout<<"["<<right->xmin()<<" "<<right->xmax()<<" "<<right->ymin()<<" "<<right->ymax()<<" "<<right->zmin()<<" "<<right->zmax()<<"]"<<std::endl; 00275 // foreach(Point* p, right->m_boundary) 00276 // std::cout<<" "<<p->x()<<" "<<p->y()<<" "<<p->z()<<std::endl; 00277 // } 00278 // left ->m_boundary<<tmp; 00279 // right->m_boundary<<tmp; 00280 00281 00282 Left=left; Right=right; 00283 } 00284 00285 //-------------------------------------------------------------------- 00286 TMPL template<class TOPOLOGY> bool SELF::inserted_regular_in(TOPOLOGY* t) { 00287 00288 typedef typename TOPOLOGY::Edge Edge; 00289 if(this->m_boundary.size()==0) return true; 00290 00291 // if(this->m_boundary.size()==1) { 00292 // std::cout<<"cell with 1 boundary point with reg "<<m_reg<<std::endl; // return false; 00293 // } 00294 if(this->m_boundary.size()==2) { 00295 t->insert(this->m_boundary[0]); 00296 t->insert(this->m_boundary[1]); 00297 t->insert(new Edge(this->m_boundary[0],this->m_boundary[1])); 00298 } else { 00299 // std::cout<<"cell with "<<this->m_boundary.size()<<" boundary points with reg "<<m_reg<<std::endl; 00300 BoundingBox bx=*this; 00301 // std::cout<<"["<<bx.xmin()<<" "<<bx.xmax()<<" "<<bx.ymin()<<" "<<bx.ymax()<<" "<<bx.zmin()<<" "<<bx.zmax()<<"]"<<std::endl; 00302 00303 std::sort(this->m_boundary.begin(), this->m_boundary.end(), along(m_reg) ); 00304 00305 foreach(Point* p, this->m_boundary) t->insert(p); 00306 00307 for(unsigned i=0;i<this->m_boundary.size();i++) { 00308 unsigned j=i+1, i0=i; 00309 // std::cout<<"i0 "<<i<<" "<<j<<std::endl; 00310 for(j=i+1; j<this->m_boundary.size() 00311 && (this->m_boundary[i0] == this->m_boundary[j]);i++, j++) ; 00312 if(j<this->m_boundary.size()) 00313 t->insert(new Edge( this->m_boundary[i0], this->m_boundary[j])); 00314 // std::cout<<"i0 "<<i<<" "<<j<<std::endl; 00315 } 00316 } 00317 00318 return true; 00319 } 00320 //-------------------------------------------------------------------- 00321 TMPL bool SELF::insert_regular(Topology* t) { 00322 return this->inserted_regular_in<Topology>(t); 00323 } 00324 //-------------------------------------------------------------------- 00325 //this insert_singular is used for detecting the singularities in the computed topology from tpl3d 00326 TMPL template<class TOPOLOGY> bool SELF::inserted_singular_in(TOPOLOGY* t) { 00327 if(this->m_boundary.size()>0) { 00328 t->insert((BoundingBox *)this); 00329 foreach(Point* p, this->m_boundary) 00330 t->insert(p); 00331 } 00332 return true; 00333 } 00334 //-------------------------------------------------------------------- 00335 TMPL bool SELF::insert_singular(Topology* t) { 00336 return this->inserted_singular_in<Topology>(t); 00337 } 00338 //-------------------------------------------------------------------- 00339 // TMPL void 00340 // SELF::check_cluster(Seq<Point*>& l, double eps) { 00341 // // Seq<Point*> res; 00342 // for(unsigned i=0; i<l.size(); i++) { 00343 // unsigned j=0; 00344 // for(j=0; j<i && distance(*l[j],*l[i])>eps;j++) ; 00345 // if(j<i) l[j]=l[i]; 00346 // } 00347 // } 00348 00349 TMPL void 00350 SELF::check_insert(Point* p, Seq<Point*>& l, double eps) { 00351 // l<<p; return ; 00352 unsigned i=0; 00353 for(i=0; i<l.size() && distance(*l[i],*p)>eps; i++) ; 00354 if(i==l.size()) l<<p; 00355 } 00356 00357 00358 } ; // namespace shape 00359 } ; // namespace mmx 00360 00361 # undef TMPL 00362 # undef Point 00363 # undef Cell 00364 # undef AlgebraicCurve 00365 # undef SELF 00366 # undef Solver 00367 # endif // SHAPE_IMPLICITCELL_H