00001
00021
00022
00023
00024
00025 #ifndef __SYNFIG_VECTOR_H
00026 #define __SYNFIG_VECTOR_H
00027
00028
00029
00030 #include "real.h"
00031 #include <cmath>
00032
00033
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
00052
00053
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
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 };
00185
00186 namespace std {
00187
00188 inline synfig::Vector::value_type
00189 abs(const synfig::Vector &rhs)
00190 { return rhs.mag(); }
00191
00192 };
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
00279
00280 #endif