00001
00021
00022
00023
00024
00025 #ifndef __SYNFIG_VECTOR_H
00026 #define __SYNFIG_VECTOR_H
00027
00028
00029
00030 #include "real.h"
00031 #include <math.h>
00032
00033
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
00045
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
00057
00058
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
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 };
00190
00191 namespace std {
00192
00193 inline synfig::Vector::value_type
00194 abs(const synfig::Vector &rhs)
00195 { return rhs.mag(); }
00196
00197 };
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
00284
00285 #endif