vector.h

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

Generated on Wed Dec 12 03:11:41 2007 for synfig by  doxygen 1.5.4