00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 # ifndef shape_cell2d_algebraic_curve_hpp
00013 # define shape_cell2d_algebraic_curve_hpp
00014
00015 # include <realroot/Interval.hpp>
00016 # include <realroot/ring_bernstein_tensor.hpp>
00017 # include <realroot/Seq.hpp>
00018 # include <shape/point.hpp>
00019 # include <shape/algebraic_curve.hpp>
00020 # include <shape/solver_implicit.hpp>
00021 # include <shape/cell2d.hpp>
00022 # include <stack>
00023
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 { namespace shape {
00033
00038 TMPL struct cell2d_subdivisor
00039 {
00040 template<class CELL> static void
00041 subdivide(CELL & cl, CELL*&, CELL*&, int v, double s);
00042 };
00043
00044
00045 TMPL
00046 template<class CELL> void
00047 cell2d_subdivisor<C,V>::subdivide(CELL& cl, CELL*& left, CELL*& right, int v, double s) {
00048
00049 typedef typename topology<C,V>::Point Point;
00050 typedef solver_implicit<C,V> Solver;
00051
00052
00053 double eps =Approximate().eps;
00054 if(v==0) {
00055 left = new CELL(cl); left ->set_xmax(s);
00056 right= new CELL(cl); right->set_xmin(s);
00057
00058 tensor::split(left->m_polynomial, right->m_polynomial, v);
00059
00060 foreach(Point* p,cl.m_special) {
00061
00062 if(p->x() < s+eps)
00063 left ->m_special << p ;
00064
00065 if(p->x() > s-eps)
00066 right->m_special << p ;
00067 }
00068
00069
00070 } else {
00071
00072 left = new CELL(cl); left->set_ymax(s);
00073 right= new CELL(cl); right->set_ymin(s);
00074
00075 tensor::split(left->m_polynomial, right->m_polynomial, v);
00076
00077 foreach(Point* p,cl.m_special) {
00078 if(p->y() < s+eps)
00079 left->m_special << p ;
00080
00081 if(p->y() > s-eps)
00082 right->m_special << p ;
00083 }
00084 }
00085
00086 }
00087
00088 template<class C, class V=default_env>
00089 class cell2d_algebraic_curve : public cell2d<C,REF> {
00090 public:
00091 typedef C Scalar;
00092 typedef topology<C,REF> Topology;
00093 typedef typename Topology::Point Point;
00094 typedef Seq<Point*> Points;
00095 typedef typename use<point_def,C,V>::Point Vector;
00096 typedef typename topology<C,REF>::Edge Edge;
00097 typedef cell<C,REF> Cell;
00098 typedef cell<C,REF> CellBase;
00099 typedef algebraic_set<C,REF> AlgebraicSet;
00100 typedef algebraic_curve<C,REF> AlgebraicCurve;
00101 typedef polynomial< Interval<C>, with<Bernstein> > Polynomial;
00102 typedef bounding_box<C,REF> BoundingBox;
00103
00104 typedef solver_implicit<C,V> Solver;
00105
00106 cell2d_algebraic_curve(const Polynomial &, const BoundingBox&, bool inter=true);
00107 cell2d_algebraic_curve(const char*, const BoundingBox&);
00108 cell2d_algebraic_curve(const typename AlgebraicSet::Polynomial& , const BoundingBox&);
00109 cell2d_algebraic_curve(AlgebraicCurve*, const BoundingBox &x);
00110 cell2d_algebraic_curve(const SELF& cl)
00111 : cell2d<C,REF>(cl.boundingBox()), m_polynomial(cl.m_polynomial) {}
00112
00113 Polynomial equation(void) { return m_polynomial; }
00114
00115 bool is_active (void) ;
00116 bool is_regular(void) ;
00117
00118 virtual void subdivide(Cell*& left, Cell*& right, int v, double s);
00119 virtual void split_position(int& v, double& t);
00120
00121 Vector gradient(const Point& p);
00122 C center_value() { return m_polynomial(0.5,0.5,0.); }
00123
00124 public:
00125 Polynomial m_polynomial;
00126 Seq<Point *> m_special;
00127 Point* m_center;
00128 };
00129
00130
00131 TMPL inline void
00132 print(SELF* cv) {
00133 typedef typename SELF::Point Point;
00134 std::cout <<"\nBox : ["<<cv->xmin()<<","<<cv->xmax()<<"] *"
00135 <<" ["<<cv->ymin()<<","<<cv->ymax()<<"]";
00136 std::cout <<"\npoint(s) s: ";
00137 foreach(Point* p, cv->s_intersections)
00138 std::cout <<" ["<<p->x()<<" "<<p->y()<<"]";
00139 std::cout << "\npoint(s) e: ";
00140 foreach(Point* p, cv->e_intersections)
00141 std::cout <<" ["<<p->x()<<" "<<p->y()<<"]";
00142 std::cout << "\npoint(s) n: ";
00143 foreach(Point* p, cv->n_intersections)
00144 std::cout <<" ["<<p->x()<<" "<<p->y()<<"]";
00145 std::cout << "\npoint(s) w: ";
00146 foreach(Point* p, cv->w_intersections)
00147 std::cout <<" ["<<p->x()<<" "<<p->y()<<"]";
00148
00149 std::cout<<std::endl;
00150
00151 std::cout << "Point(s) sing: ";
00152 foreach(Point* p, cv->m_special)
00153 std::cout <<" ["<<p->x()<<" "<<p->y()<<"]";
00154 std::cout<<std::endl;
00155 }
00156
00157 TMPL
00158 SELF::cell2d_algebraic_curve(const Polynomial& pol, const BoundingBox& bx, bool inter): cell2d<C,REF>(bx), m_polynomial(pol)
00159 {
00160
00161 }
00162
00163 TMPL
00164 SELF::cell2d_algebraic_curve(const typename AlgebraicSet::Polynomial& p, const BoundingBox & b): cell2d<C,REF>(b)
00165 {
00166
00167 Seq<mmx::GMP::rational> bx;
00168 bx<<as<mmx::GMP::rational>(b.xmin());
00169 bx<<as<mmx::GMP::rational>(b.xmax());
00170 bx<<as<mmx::GMP::rational>(b.ymin());
00171 bx<<as<mmx::GMP::rational>(b.ymax());
00172
00173 tensor::bernstein<mmx::GMP::rational> polq(p.rep(),bx);
00174
00175 let::assign(m_polynomial.rep(),polq);
00176
00177 Solver::extremal(this->m_special, p, b);
00178
00179
00180
00181
00182
00183 }
00184
00185
00186 TMPL
00187 SELF::cell2d_algebraic_curve(const char* s, const BoundingBox & b): cell2d<C,REF>(b)
00188 {
00189 Seq<mmx::GMP::rational> bx;
00190 bx<<as<mmx::GMP::rational>(b.xmin());
00191 bx<<as<mmx::GMP::rational>(b.xmax());
00192 bx<<as<mmx::GMP::rational>(b.ymin());
00193 bx<<as<mmx::GMP::rational>(b.ymax());
00194
00195 typename AlgebraicSet::Polynomial pol(s);
00196 tensor::bernstein<mmx::GMP::rational> polq(s,bx);
00197
00198 let::assign(m_polynomial.rep(),polq);
00199
00200 Solver::extremal(this->m_special, pol, b);
00201 foreach(Point* p,this-> m_special)
00202 std::cout<<"**extremal point: "<<p->x()<<" "<<p->y() <<std::endl;
00203 }
00204
00205
00206 TMPL
00207 SELF::cell2d_algebraic_curve(AlgebraicCurve* cv, const BoundingBox & b)
00208 {
00209 new (this) SELF(cv->equation(),b );
00210 }
00211
00212
00213 TMPL bool
00214 SELF::is_regular() {
00215
00216
00217 if(this->m_special.size()>1) return false;
00218
00219 if (this->m_special.size()==0) {
00220 if(!has_sign_variation(m_polynomial)) return true;
00221
00222 Polynomial dx= diff(m_polynomial,0);
00223 if(!has_sign_variation(dx)) return true;
00224
00225 Polynomial dy= diff(m_polynomial,1);
00226 if(!has_sign_variation(dy)) return true;
00227
00228 return false;
00229
00230
00231
00232
00233 }
00234
00235
00236
00237 if(this->m_special.size()==1) {
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 return false;
00253 }
00254
00255 return true;
00256 }
00257
00258
00259 TMPL bool
00260 SELF::is_active() {
00261 return (has_sign_variation(this->m_polynomial));
00262 }
00263
00264 TMPL void
00265 SELF::split_position(int& v, double& s) {
00266 double sx = (this->xmax()-this->xmin());
00267 double sy = (this->ymax()-this->ymin());
00268 if(sx<sy) {
00269 v=1;
00270 s=(this->ymax()+this->ymin())/2;
00271 } else {
00272 v=0;
00273 s=(this->xmax()+this->xmin())/2;
00274 }
00275 }
00276
00277 TMPL void
00278 SELF::subdivide(Cell*& Left, Cell*& Right, int v, double s) {
00279 cell2d_subdivisor<C,V>::subdivide( *this,(SELF*&)Left,(SELF*&)Right,v,s);
00280 }
00281
00282 TMPL typename SELF::Vector
00283 SELF::gradient(const Point& p) {
00284 Polynomial
00285 dx= diff(m_polynomial,0),
00286 dy= diff(m_polynomial,1);
00287 double
00288 u0= (p[0]-this->xmin())/(this->xmax()-this->xmin()),
00289 u1= (p[1]-this->ymin())/(this->ymax()-this->ymin());
00290 Vector v;
00291 v[0] = dx(u0,u1);
00292 v[1] = dy(u0,u1);
00293 return v;
00294 }
00295
00296 } ;
00297 } ;
00298 # undef Solver
00299 # undef SELF
00300 # undef REF
00301 # undef TMPL
00302 # undef TMPL1
00303 # undef STACK
00304 # endif // shape_cell2d_algebraic_curve_hpp