- Main Page
- Related Pages
- Namespaces
- Classes
- Files

# 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