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

Generated on Wed Aug 15 05:00:23 2007 for synfig by  doxygen 1.5.3