1 /* === S Y N F I G ========================================================= */
3 ** \brief Various discreet type definitions
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
10 ** This package is free software; you can redistribute it and/or
11 ** modify it under the terms of the GNU General Public License as
12 ** published by the Free Software Foundation; either version 2 of
13 ** the License, or (at your option) any later version.
15 ** This package is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ** General Public License for more details.
21 /* ========================================================================= */
23 /* === S T A R T =========================================================== */
25 #ifndef __SYNFIG_VECTOR_H
26 #define __SYNFIG_VECTOR_H
28 /* === H E A D E R S ======================================================= */
34 /* === M A C R O S ========================================================= */
40 extern "C" { int _isnan(double x); }
45 // For some reason isnan() isn't working on macosx any more.
46 // This is a quick fix.
47 #if defined(__APPLE__) && !defined(SYNFIG_ISNAN_FIX)
51 inline bool isnan(double x) { return x != x; }
52 inline bool isnan(float x) { return x != x; }
53 #define SYNFIG_ISNAN_FIX 1
57 /* === T Y P E D E F S ===================================================== */
59 /* === C L A S S E S & S T R U C T S ======================================= */
69 typedef Real value_type;
75 Vector(): _x(0.0), _y(0.0) { };
76 Vector(const value_type &x, const value_type &y):_x(x),_y(y) { };
78 bool is_valid()const { return !(isnan(_x) || isnan(_y)); }
81 operator[](const int& i)
85 operator[](const int& i) const
89 operator+=(const Vector &rhs)
97 operator-=(const Vector &rhs)
105 operator*=(const value_type &rhs)
113 operator/=(const value_type &rhs)
115 value_type tmp=1.0/rhs;
122 operator+(const Vector &rhs)const
123 { return Vector(*this)+=rhs; }
126 operator-(const Vector &rhs)const
127 { return Vector(*this)-=rhs; }
130 operator*(const value_type &rhs)const
131 { return Vector(*this)*=rhs; }
134 operator/(const value_type &rhs)const
135 { return Vector(*this)/=rhs; }
139 { return Vector(-_x,-_y); }
142 operator*(const Vector &rhs)const
143 { return _x*rhs._x+_y*rhs._y; }
146 operator==(const Vector &rhs)const
147 { return _x==rhs._x && _y==rhs._y; }
150 operator!=(const Vector &rhs)const
151 { return _y!=rhs._y || _x!=rhs._x; }
153 //! Returns the squared magnitude of the vector
154 value_type mag_squared()const
155 { return _x*_x+_y*_y; }
157 //! Returns the magnitude of the vector
158 value_type mag()const
159 { return sqrt(mag_squared()); }
161 //! Returns the reciprocal of the magnitude of the vector
162 value_type inv_mag()const
163 { return 1.0/sqrt(mag_squared()); }
165 //! Returns a normalized version of the vector
167 { return (*this)*inv_mag(); }
169 //! Returns a perpendicular version of the vector
171 { return Vector(_y,-_x); }
174 { return Angle::rad(atan2(_y, _x)); }
176 bool is_equal_to(const Vector& rhs)const
178 static const value_type epsilon(0.0000000000001);
179 // return (_x>rhs._x)?_x-rhs._x<=epsilon:rhs._x-_x<=epsilon && (_y>rhs._y)?_y-rhs._y<=epsilon:rhs._y-_y<=epsilon;
180 return (*this-rhs).mag_squared()<=epsilon;
183 static const Vector zero() { return Vector(0,0); }
189 typedef Vector Point;
193 }; // END of namespace synfig
197 inline synfig::Vector::value_type
198 abs(const synfig::Vector &rhs)
199 { return rhs.mag(); }
201 }; // END of namespace std
203 #include <ETL/bezier>
208 class bezier_base<synfig::Vector,float> : public std::unary_function<float,synfig::Vector>
211 typedef synfig::Vector value_type;
212 typedef float time_type;
215 bezier_base<synfig::Vector::value_type,time_type> bezier_x,bezier_y;
220 affine_combo<value_type,time_type> affine_func;
225 const value_type &a, const value_type &b, const value_type &c, const value_type &d,
226 const time_type &r=0.0, const time_type &s=1.0):
227 a(a),b(b),c(c),d(d) { set_rs(r,s); sync(); }
231 bezier_x[0]=a[0],bezier_y[0]=a[1];
232 bezier_x[1]=b[0],bezier_y[1]=b[1];
233 bezier_x[2]=c[0],bezier_y[2]=c[1];
234 bezier_x[3]=d[0],bezier_y[3]=d[1];
240 operator()(time_type t)const
242 return synfig::Vector(bezier_x(t),bezier_y(t));
245 void evaluate(time_type t, value_type &f, value_type &df) const
247 t=(t-get_r())/get_dt();
249 const value_type p1 = affine_func(
253 const value_type p2 = affine_func(
258 f = affine_func(p1,p2,t);
262 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); }
263 void set_r(time_type new_r) { bezier_x.set_r(new_r); bezier_y.set_r(new_r); }
264 void set_s(time_type new_s) { bezier_x.set_s(new_s); bezier_y.set_s(new_s); }
265 const time_type &get_r()const { return bezier_x.get_r(); }
266 const time_type &get_s()const { return bezier_x.get_s(); }
267 time_type get_dt()const { return bezier_x.get_dt(); }
274 operator[](int i) const
277 //! Bezier curve intersection function
278 time_type intersect(const bezier_base<value_type,time_type> &/*x*/, time_type /*near*/=0.0)const
287 /* === E N D =============================================================== */