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