vector.h

Go to the documentation of this file.
00001 /* === S Y N F I G ========================================================= */
00021 /* ========================================================================= */
00022 
00023 /* === S T A R T =========================================================== */
00024 
00025 #ifndef __SYNFIG_VECTOR_H
00026 #define __SYNFIG_VECTOR_H
00027 
00028 /* === H E A D E R S ======================================================= */
00029 
00030 #include "real.h"
00031 #include <cmath>
00032 
00033 /* === M A C R O S ========================================================= */
00034 
00035 #ifndef isnan
00036 
00037 #ifdef WIN32
00038 #include <float.h>
00039 #ifndef isnan
00040 extern "C" { int _isnan(double x); }
00041 #define isnan _isnan
00042 #endif
00043 #endif
00044 
00045 #ifdef __APPLE__
00046 #define isnan __isnanf
00047 #endif
00048 
00049 #endif
00050 
00051 /* === T Y P E D E F S ===================================================== */
00052 
00053 /* === C L A S S E S & S T R U C T S ======================================= */
00054 
00055 namespace synfig {
00056 
00060 class Vector
00061 {
00062 public:
00063     typedef Real value_type;
00064 
00065 private:
00066     value_type _x, _y;
00067 
00068 public:
00069     Vector() { };
00070     Vector(const value_type &x, const value_type &y):_x(x),_y(y) { };
00071 
00072     bool is_valid()const { return !(isnan(_x) || isnan(_y)); }
00073     
00074     value_type &
00075     operator[](const int& i)
00076     { return (&_x)[i] ; }
00077 
00078     const value_type &
00079     operator[](const int& i) const
00080     { return (&_x)[i] ; }
00081     
00082     const Vector &
00083     operator+=(const Vector &rhs)
00084     {
00085         _x+=rhs._x;
00086         _y+=rhs._y;
00087         return *this;
00088     }
00089     
00090     const Vector &
00091     operator-=(const Vector &rhs)
00092     {
00093         _x-=rhs._x;
00094         _y-=rhs._y;
00095         return *this;
00096     }
00097     
00098     const Vector &
00099     operator*=(const value_type &rhs)
00100     {
00101         _x*=rhs;
00102         _y*=rhs;
00103         return *this;
00104     }
00105     
00106     const Vector &
00107     operator/=(const value_type &rhs)
00108     {
00109         value_type tmp=1.0/rhs;
00110         _x*=tmp;
00111         _y*=tmp;
00112         return *this;
00113     }
00114         
00115     Vector
00116     operator+(const Vector &rhs)const
00117         { return Vector(*this)+=rhs; }
00118 
00119     Vector
00120     operator-(const Vector &rhs)const
00121         { return Vector(*this)-=rhs; }
00122 
00123     Vector
00124     operator*(const value_type &rhs)const
00125         { return Vector(*this)*=rhs; }
00126 
00127     Vector
00128     operator/(const value_type &rhs)const
00129         { return Vector(*this)/=rhs; }
00130 
00131     Vector
00132     operator-()const
00133         { return Vector(-_x,-_y); }
00134 
00135     value_type
00136     operator*(const Vector &rhs)const
00137         { return _x*rhs._x+_y*rhs._y; }
00138 
00139     bool
00140     operator==(const Vector &rhs)const
00141         { return _x==rhs._x && _y==rhs._y; }
00142     
00143     bool
00144     operator!=(const Vector &rhs)const
00145         { return _y!=rhs._y || _x!=rhs._x; }
00146     
00148     value_type mag_squared()const
00149         { return _x*_x+_y*_y; }
00150     
00152     value_type mag()const
00153         { return sqrt(mag_squared()); }
00154 
00156     value_type inv_mag()const
00157         { return 1.0/sqrt(mag_squared()); }
00158 
00160     Vector norm()const
00161         { return (*this)*inv_mag(); }
00162 
00164     Vector perp()const
00165         { return Vector(_y,-_x); }
00166         
00167     bool is_equal_to(const Vector& rhs)const
00168     {
00169         static const value_type epsilon(0.0000000000001);
00170 //      return (_x>rhs._x)?_x-rhs._x<=epsilon:rhs._x-_x<=epsilon && (_y>rhs._y)?_y-rhs._y<=epsilon:rhs._y-_y<=epsilon;
00171         return (*this-rhs).mag_squared()<=epsilon;
00172     }
00173     
00174     static const Vector zero() { return Vector(0,0); }
00175 };
00176 
00180 typedef Vector Point;
00181 
00182 
00183 
00184 }; // END of namespace synfig
00185 
00186 namespace std {
00187 
00188 inline synfig::Vector::value_type
00189 abs(const synfig::Vector &rhs)
00190     { return rhs.mag(); }
00191 
00192 }; // END of namespace std
00193 
00194 #include <ETL/bezier>
00195 
00196 _ETL_BEGIN_NAMESPACE
00197 
00198 template <>
00199 class bezier_base<synfig::Vector,float> : public std::unary_function<float,synfig::Vector>
00200 {
00201 public:
00202     typedef synfig::Vector value_type;
00203     typedef float time_type;
00204 private:
00205 
00206     bezier_base<synfig::Vector::value_type,time_type> bezier_x,bezier_y;
00207 
00208     value_type a,b,c,d;
00209 
00210 protected:
00211     affine_combo<value_type,time_type> affine_func; 
00212 
00213 public:
00214     bezier_base() { }
00215     bezier_base(
00216         const value_type &a, const value_type &b, const value_type &c, const value_type &d,
00217         const time_type &r=0.0, const time_type &s=1.0):
00218         a(a),b(b),c(c),d(d) { set_rs(r,s); sync(); }
00219         
00220     void sync()
00221     {
00222         bezier_x[0]=a[0],bezier_y[0]=a[1];
00223         bezier_x[1]=b[0],bezier_y[1]=b[1];
00224         bezier_x[2]=c[0],bezier_y[2]=c[1];
00225         bezier_x[3]=d[0],bezier_y[3]=d[1];
00226         bezier_x.sync();
00227         bezier_y.sync();
00228     }
00229 
00230     value_type
00231     operator()(time_type t)const
00232     {
00233         return synfig::Vector(bezier_x(t),bezier_y(t));
00234     }
00235     
00236     void evaluate(time_type t, value_type &f, value_type &df) const
00237     {
00238         t=(t-get_r())/get_dt();
00239         
00240         const value_type p1 = affine_func(
00241                             affine_func(a,b,t),
00242                             affine_func(b,c,t)
00243                             ,t);
00244         const value_type p2 = affine_func(
00245                             affine_func(b,c,t),
00246                             affine_func(c,d,t)
00247                         ,t);
00248         
00249         f = affine_func(p1,p2,t);
00250         df = (p2-p1)*3;
00251     }
00252 
00253     void set_rs(time_type new_r, time_type new_s) { bezier_x.set_rs(new_r,new_s); bezier_y.set_rs(new_r,new_s); }
00254     void set_r(time_type new_r) { bezier_x.set_r(new_r); bezier_y.set_r(new_r); }
00255     void set_s(time_type new_s) { bezier_x.set_s(new_s); bezier_y.set_s(new_s); }
00256     const time_type &get_r()const { return bezier_x.get_r(); }
00257     const time_type &get_s()const { return bezier_x.get_s(); }
00258     time_type get_dt()const { return bezier_x.get_dt(); }
00259 
00260     value_type &
00261     operator[](int i)
00262     { return (&a)[i]; }
00263 
00264     const value_type &
00265     operator[](int i) const
00266     { return (&a)[i]; }
00267 
00269     time_type intersect(const bezier_base<value_type,time_type> &x, time_type near=0.0)const
00270     {
00271         return 0;
00272     }
00273 };
00274 
00275 _ETL_END_NAMESPACE
00276 
00277 
00278 /* === E N D =============================================================== */
00279 
00280 #endif

Generated on Fri Jun 23 15:20:50 2006 for synfig by  doxygen 1.4.6