synfig-core  1.0.3
vector.h
Go to the documentation of this file.
1 /* === S Y N F I G ========================================================= */
22 /* ========================================================================= */
23 
24 /* === S T A R T =========================================================== */
25 
26 #ifndef __SYNFIG_VECTOR_H
27 #define __SYNFIG_VECTOR_H
28 
29 /* === H E A D E R S ======================================================= */
30 
31 #include "angle.h"
32 #include "real.h"
33 #include <cmath>
34 
35 /* === M A C R O S ========================================================= */
36 
37 // For some reason isnan() isn't working on macosx any more.
38 // This is a quick fix.
39 #if defined(__APPLE__) && !defined(SYNFIG_ISNAN_FIX)
40 #ifdef isnan
41 #undef isnan
42 #endif
43 inline bool isnan(double x) { return x != x; }
44 inline bool isnan(float x) { return x != x; }
45 #define SYNFIG_ISNAN_FIX 1
46 #ifdef isinf
47 #undef isinf
48 #endif
49 inline bool isinf(double x) { return !isnan(x) && isnan(x - x); }
50 inline bool isinf(float x) { return !isnan(x) && isnan(x - x); }
51 #define SYNFIG_ISINF_FIX 1
52 #else
53 #ifndef isnan
54 #define isnan(x) (std::isnan)(x)
55 #endif
56 #ifndef isinf
57 #define isinf(x) (std::isinf)(x)
58 #endif
59 #endif
60 
61 
62 /* === T Y P E D E F S ===================================================== */
63 
64 /* === C L A S S E S & S T R U C T S ======================================= */
65 
66 namespace synfig {
67 
71 class Vector
72 {
73 public:
74  typedef Real value_type;
75 
76 private:
77  value_type _x, _y;
78 
79 public:
80  Vector(): _x(0.0), _y(0.0) { };
81  Vector(const value_type &x, const value_type &y):_x(x),_y(y) { };
82  Vector(const value_type &radius, const Angle &angle):
83  _x(radius*Angle::cos(angle).get()),
84  _y(radius*Angle::sin(angle).get())
85  { };
86 
87  bool is_valid()const { return !(isnan(_x) || isnan(_y)); }
88  bool is_nan_or_inf()const { return isnan(_x) || isnan(_y) || isinf(_x) || isinf(_y); }
89 
90  value_type &
91  operator[](const int& i)
92  { return i?_y:_x; }
93 
94  const value_type &
95  operator[](const int& i) const
96  { return i?_y:_x; }
97 
98  const Vector &
99  operator+=(const Vector &rhs)
100  {
101  _x+=rhs._x;
102  _y+=rhs._y;
103  return *this;
104  }
105 
106  const Vector &
107  operator-=(const Vector &rhs)
108  {
109  _x-=rhs._x;
110  _y-=rhs._y;
111  return *this;
112  }
113 
114  const Vector &
115  operator*=(const value_type &rhs)
116  {
117  _x*=rhs;
118  _y*=rhs;
119  return *this;
120  }
121 
122  const Vector &
123  operator/=(const value_type &rhs)
124  {
125  value_type tmp=1.0/rhs;
126  _x*=tmp;
127  _y*=tmp;
128  return *this;
129  }
130 
131  Vector
132  operator+(const Vector &rhs)const
133  { return Vector(*this)+=rhs; }
134 
135  Vector
136  operator-(const Vector &rhs)const
137  { return Vector(*this)-=rhs; }
138 
139  Vector
140  operator*(const value_type &rhs)const
141  { return Vector(*this)*=rhs; }
142 
143  Vector
144  operator/(const value_type &rhs)const
145  { return Vector(*this)/=rhs; }
146 
147  Vector
148  operator-()const
149  { return Vector(-_x,-_y); }
150 
151  value_type
152  operator*(const Vector &rhs)const
153  { return _x*rhs._x+_y*rhs._y; }
154 
155  bool
156  operator==(const Vector &rhs)const
157  { return _x==rhs._x && _y==rhs._y; }
158 
159  bool
160  operator!=(const Vector &rhs)const
161  { return _y!=rhs._y || _x!=rhs._x; }
162 
165  { return _x*_x+_y*_y; }
166 
169  { return sqrt(mag_squared()); }
170 
173  { return 1.0/sqrt(mag_squared()); }
174 
176  Vector norm()const
177  { return (*this)*inv_mag(); }
178 
180  Vector perp()const
181  { return Vector(_y,-_x); }
182 
183  Angle angle()const
184  { return Angle::rad(atan2(_y, _x)); }
185 
186  bool is_equal_to(const Vector& rhs)const
187  {
188  static const value_type epsilon(0.0000000000001);
189 // return (_x>rhs._x)?_x-rhs._x<=epsilon:rhs._x-_x<=epsilon && (_y>rhs._y)?_y-rhs._y<=epsilon:rhs._y-_y<=epsilon;
190  return (*this-rhs).mag_squared()<=epsilon;
191  }
192 
193  static const Vector zero() { return Vector(0,0); }
194 
195  Vector multiply_coords(const Vector &rhs) const
196  { return Vector(_x*rhs._x, _y*rhs._y); }
197  Vector divide_coords(const Vector &rhs) const
198  { return Vector(_x/rhs._x, _y/rhs._y); }
200  { return Vector(1.0/_x, 1.0/_y); }
201  Vector rotate(const Angle &rhs) const
202  {
203  value_type s = Angle::sin(rhs).get();
204  value_type c = Angle::cos(rhs).get();
205  return Vector(c*_x - s*_y, s*_x + c*_y);
206  }
207 };
208 
212 typedef Vector Point;
213 
214 
215 
216 }; // END of namespace synfig
217 
218 namespace std {
219 
221 abs(const synfig::Vector &rhs)
222  { return rhs.mag(); }
223 
224 }; // END of namespace std
225 
226 #include <ETL/bezier>
227 
228 _ETL_BEGIN_NAMESPACE
229 
230 template <>
231 class bezier_base<synfig::Vector,float> : public std::unary_function<float,synfig::Vector>
232 {
233 public:
235  typedef float time_type;
236 private:
237 
238  bezier_base<synfig::Vector::value_type,time_type> bezier_x,bezier_y;
239 
240  value_type a,b,c,d;
241 
242 protected:
243  affine_combo<value_type,time_type> affine_func;
244 
245 public:
247  bezier_base(
248  const value_type &a, const value_type &b, const value_type &c, const value_type &d,
249  const time_type &r=0.0, const time_type &s=1.0):
250  a(a),b(b),c(c),d(d) { set_rs(r,s); sync(); }
251 
252  void sync()
253  {
254  bezier_x[0]=a[0],bezier_y[0]=a[1];
255  bezier_x[1]=b[0],bezier_y[1]=b[1];
256  bezier_x[2]=c[0],bezier_y[2]=c[1];
257  bezier_x[3]=d[0],bezier_y[3]=d[1];
258  bezier_x.sync();
259  bezier_y.sync();
260  }
261 
262  value_type
263  operator()(time_type t)const
264  {
265  return synfig::Vector(bezier_x(t),bezier_y(t));
266  }
267 
268  void evaluate(time_type t, value_type &f, value_type &df) const
269  {
270  t=(t-get_r())/get_dt();
271 
272  const value_type p1 = affine_func(
273  affine_func(a,b,t),
274  affine_func(b,c,t)
275  ,t);
276  const value_type p2 = affine_func(
277  affine_func(b,c,t),
278  affine_func(c,d,t)
279  ,t);
280 
281  f = affine_func(p1,p2,t);
282  df = (p2-p1)*3;
283  }
284 
285  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); }
286  void set_r(time_type new_r) { bezier_x.set_r(new_r); bezier_y.set_r(new_r); }
287  void set_s(time_type new_s) { bezier_x.set_s(new_s); bezier_y.set_s(new_s); }
288  const time_type &get_r()const { return bezier_x.get_r(); }
289  const time_type &get_s()const { return bezier_x.get_s(); }
290  time_type get_dt()const { return bezier_x.get_dt(); }
291 
292  value_type &
293  operator[](int i)
294  { return (&a)[i]; }
295 
296  const value_type &
297  operator[](int i) const
298  { return (&a)[i]; }
299 
301  time_type intersect(const bezier_base<value_type,time_type> &/*x*/, time_type /*near*/=0.0)const
302  {
303  return 0;
304  }
305 };
306 
307 _ETL_END_NAMESPACE
308 
309 
310 /* === E N D =============================================================== */
311 
312 #endif