shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/curve_rational.hpp
Go to the documentation of this file.
00001 /*****************************************************************************
00002  * M a t h e m a g i x
00003  *****************************************************************************
00004  * RationalCurve
00005  * 2010-04-03
00006  *****************************************************************************
00007  *               Copyright (C) 2006 INRIA Sophia-Antipolis
00008  *****************************************************************************
00009  * Comments :
00010  ****************************************************************************/
00011 # ifndef shape_curve_rational_hpp
00012 # define shape_curve_rational_hpp
00013 
00014 # include <realroot/GMP.hpp>
00015 # include <realroot/polynomial_bernstein.hpp>
00016 # include <shape/graphic.hpp>
00017 # include <shape/point.hpp>
00018 # include <shape/parametric_curve.hpp>
00019 
00020 # define TMPL_DEF template<class C, class V=default_env>
00021 # define TMPL template<class C, class V>
00022 # define TMPL1 template<class V>
00023 # define REF     REF_OF(V)
00024 # define SELF curve_rational<C,V>
00025 # define GRAPHIC graphic<C,V>
00026 # define AXEL viewer<axel,V>
00027 //====================================================================
00028 namespace mmx {
00029 namespace shape {
00030 
00031 struct curve_rational_def {};
00032 
00033 template<> struct use<curve_rational_def> {
00034   typedef double Range;
00035   typedef polynomial< double, with<Bernstein> > Polynomial;
00036 };
00037 
00038 TMPL_DEF
00039 class curve_rational : public parametric_curve<C,V> {
00040 public:
00041   typedef bounding_box<C,V>   BoundingBox;
00042   typedef parametric_curve<C,V> ParametricCurve;
00043   typedef typename ParametricCurve::Scalar Scalar;
00044   typedef typename ParametricCurve::Point Point;
00045   typedef typename use<curve_rational_def,V>::Polynomial Polynomial;
00046 
00047   curve_rational(void) :ParametricCurve(), m_tmin(0), m_tmax(1) {}
00048 
00049   curve_rational(const BoundingBox & box): 
00050     ParametricCurve(box), m_tmin(0), m_tmax(1) {}
00051   
00052   curve_rational(const Polynomial& X, const Polynomial& Y, const Polynomial& Z, const Polynomial& W=1)
00053     : ParametricCurve(), m_tmin(0), m_tmax(1), m_w(W) 
00054   {
00055     m_p<<X; m_p<<Y; m_p<<Z;
00056   }
00057 
00058   curve_rational(double m, double M, const Polynomial& X, const Polynomial& Y, const Polynomial& Z, const Polynomial& W=1)
00059     : ParametricCurve(), m_tmin(m), m_tmax(M), m_w(W) 
00060   {
00061     m_p<<X; m_p<<Y; m_p<<Z;
00062   }
00063 
00064   curve_rational(const SELF& c)
00065     : ParametricCurve(), m_tmin(c.tmin()), m_tmax(c.tmax()),  m_w(c.m_w) 
00066   {
00067     m_p=c.m_p; 
00068   }
00069 
00070   int dimension() const { return m_p.size();}
00071 
00072  ~curve_rational(void) {};
00073 
00074   double tmin(void) const { return this->m_tmin; }
00075   double tmax(void) const { return this->m_tmax; }
00076   void   set_range(double tmin, double tmax);
00077 
00078   Point* eval (const double& t) const;
00079   Point* operator() (double t);
00080   void   eval   (double t, double * x, double * y, double * z)  const ;
00081   void   eval   (Point&,  Scalar ) const;
00082 
00083   void   subdivide (ParametricCurve*& a, ParametricCurve*& b, double t ) const ;
00084 
00085   const Polynomial& denominator()    const { return m_w; }
00086   const Polynomial& numerator(int i) const { return m_p[i]; }
00087 
00088   Seq<Point *> critical_points(void) ;
00089   Seq<Point *> extremal_points(void) ;
00090   Seq<Point *> singular_points(void) ;
00091   
00092 private:
00093   double m_tmin ;
00094   double m_tmax ;
00095   
00096   Polynomial m_w;
00097   Seq<Polynomial> m_p;
00098 };
00099 
00100 TMPL typename SELF::Point* 
00101 SELF::eval(const double& t) const {
00102   Scalar v=as<Scalar>(t);
00103   double w = as<double>(m_w(v));
00104   Point* p = new Point(m_p[0](v)/w, m_p[1](v)/w, m_p[2](v)/w);
00105   return p ;
00106 }
00107 
00108 TMPL void 
00109 SELF::eval(Point& v, Scalar p) const {
00110   Scalar w=m_w(p);
00111   v.setx(m_p[0](p)/w);
00112   v.sety(m_p[1](p)/w);
00113   v.setz(m_p[2](p)/w);
00114 }
00115 
00116 TMPL typename SELF::Point* 
00117 SELF::operator() (double t) { return eval(t); }
00118 
00119 
00120 TMPL void 
00121 SELF::set_range(double tmin, double tmax) {
00122   m_tmin=tmin;                                           
00123   m_tmax=tmax;                                           
00124 }
00125 
00126   TMPL Seq<typename SELF::Point *> 
00127 SELF::critical_points(void) {
00128   Seq<Point *> l ;
00129   // ...
00130   return l ;
00131 }
00132 
00133 TMPL Seq<typename SELF::Point *> 
00134 SELF::extremal_points(void) {
00135    Seq<Point *> l ;
00136    // ...
00137    return l ;
00138 }
00139 
00140 TMPL Seq<typename SELF::Point *> 
00141 SELF::singular_points(void)
00142 {
00143    Seq<Point *> l ;
00144    // ...
00145    return l ;
00146 }
00147 TMPL void
00148 SELF::subdivide(ParametricCurve*& a, ParametricCurve*& b, double t ) const {
00149   SELF
00150     * ar = new SELF(*this),
00151     * br = new SELF(*this);
00152   ar->set_range(tmin(),t);
00153   br->set_range(t,tmax());
00154 
00155   a = dynamic_cast<ParametricCurve*>(ar);
00156   b = dynamic_cast<ParametricCurve*>(br);
00157 
00158 }
00159 
00160 TMPL struct viewer; struct axel;
00161 TMPL AXEL&
00162 operator<<(AXEL& os, const SELF& c) {
00163   os<<"\n <curve type=\"rational\"  color=\""<<(int)(255*os.color.r)<<" "<<(int)(255*os.color.g)<<" "<<(int)(255*os.color.b)<<"\">\n";
00164   os<<"   <domain>"<< c.tmin()<<" "<<c.tmax()<<"</domain>\n";
00165   for(int i=0; i<c.dimension();i++){
00166     os<<"   <polynomial>";
00167     print(os,c.numerator(i),variables("t"));
00168     os<<"</polynomial>\n";
00169   }
00170   os<<"   <polynomial>";
00171   print(os,c.denominator(),variables("t"));
00172   os<<"</polynomial>\n";
00173   os<<" </curve>\n";
00174   return os;
00175 }
00176 //--------------------------------------------------------------------
00177 TMPL GRAPHIC*
00178 as_graphic(const SELF& c, unsigned N= 100) {
00179   typedef typename curve_pl<C,V>::Point Point;
00180   typedef typename curve_pl<C,V>::Edge  Edge;
00181   typedef C                    Scalar;
00182 
00183 
00184   GRAPHIC* r = new GRAPHIC( GRAPHIC::E_LINE, N+1, 2*N);
00185   
00186   Scalar t=c.tmin(),dt=(c.tmax()-c.tmin())/N;
00187   for(unsigned i=0;i<=N;i++) {
00188     Scalar w=c.denominator()(t);
00189     for(unsigned j=0;j<3;j++) 
00190       r->vertices[3*i+j]=c.numerator(j)(t)/w;
00191     t+=dt;
00192   }
00193 
00194   for(unsigned i=0;i<N;i++) {
00195     r->indices[2*i]=i;
00196     r->indices[2*i+1]=i+1;
00197   }
00198   return r;
00199 }
00200 
00201 //====================================================================
00202 } ; // namespace shape
00203 //====================================================================
00204 } ; // namespace mmx
00205 //====================================================================
00206 # undef TMPL
00207 # undef TMPL1
00208 # undef TMPL_DEF
00209 # undef REF
00210 # undef Scalar
00211 # undef Point
00212 # undef SELF
00213 # undef ParametricCurve
00214 # undef AXEL
00215 # undef GRAPHIC
00216 # endif // shape_curve_rational_hpp