00001
00022
00023
00024
00025
00026 #ifndef __SYNFIG_VECTOR_H
00027 #define __SYNFIG_VECTOR_H
00028
00029
00030
00031 #include "angle.h"
00032 #include "real.h"
00033 #include <math.h>
00034
00035
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
00047
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
00059
00060
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
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 };
00195
00196 namespace std {
00197
00198 inline synfig::Vector::value_type
00199 abs(const synfig::Vector &rhs)
00200 { return rhs.mag(); }
00201
00202 };
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> &, time_type =0.0)const
00280 {
00281 return 0;
00282 }
00283 };
00284
00285 _ETL_END_NAMESPACE
00286
00287
00288
00289
00290 #endif