more updates
[synfig.git] / synfig-core / trunk / src / synfig / vector.h
1 /* === S I N F G =========================================================== */
2 /*!     \file vector.h
3 **      \brief Various discreet type definitions
4 **
5 **      $Id: vector.h,v 1.2 2005/01/23 04:03:21 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === S T A R T =========================================================== */
23
24 #ifndef __SINFG_VECTOR_H
25 #define __SINFG_VECTOR_H
26
27 /* === H E A D E R S ======================================================= */
28
29 #include "real.h"
30 #include <cmath>
31
32 /* === M A C R O S ========================================================= */
33
34 #ifndef isnan
35
36 #ifdef WIN32
37 #include <float.h>
38 #ifndef isnan
39 extern "C" { int _isnan(double x); }
40 #define isnan _isnan
41 #endif
42 #endif
43
44 #ifdef __APPLE__
45 #define isnan __isnanf
46 #endif
47
48 #endif
49
50 /* === T Y P E D E F S ===================================================== */
51
52 /* === C L A S S E S & S T R U C T S ======================================= */
53
54 namespace sinfg {
55
56 /*!     \class Vector
57 **      \todo writeme
58 */
59 class Vector
60 {
61 public:
62         typedef Real value_type;
63
64 private:
65         value_type _x, _y;
66
67 public:
68         Vector() { };
69         Vector(const value_type &x, const value_type &y):_x(x),_y(y) { };
70
71         bool is_valid()const { return !(isnan(_x) || isnan(_y)); }
72         
73         value_type &
74         operator[](const int& i)
75         { return (&_x)[i] ; }
76
77         const value_type &
78         operator[](const int& i) const
79         { return (&_x)[i] ; }
80         
81         const Vector &
82         operator+=(const Vector &rhs)
83         {
84                 _x+=rhs._x;
85                 _y+=rhs._y;
86                 return *this;
87         }
88         
89         const Vector &
90         operator-=(const Vector &rhs)
91         {
92                 _x-=rhs._x;
93                 _y-=rhs._y;
94                 return *this;
95         }
96         
97         const Vector &
98         operator*=(const value_type &rhs)
99         {
100                 _x*=rhs;
101                 _y*=rhs;
102                 return *this;
103         }
104         
105         const Vector &
106         operator/=(const value_type &rhs)
107         {
108                 value_type tmp=1.0/rhs;
109                 _x*=tmp;
110                 _y*=tmp;
111                 return *this;
112         }
113                 
114         Vector
115         operator+(const Vector &rhs)const
116                 { return Vector(*this)+=rhs; }
117
118         Vector
119         operator-(const Vector &rhs)const
120                 { return Vector(*this)-=rhs; }
121
122         Vector
123         operator*(const value_type &rhs)const
124                 { return Vector(*this)*=rhs; }
125
126         Vector
127         operator/(const value_type &rhs)const
128                 { return Vector(*this)/=rhs; }
129
130         Vector
131         operator-()const
132                 { return Vector(-_x,-_y); }
133
134         value_type
135         operator*(const Vector &rhs)const
136                 { return _x*rhs._x+_y*rhs._y; }
137
138         bool
139         operator==(const Vector &rhs)const
140                 { return _x==rhs._x && _y==rhs._y; }
141         
142         bool
143         operator!=(const Vector &rhs)const
144                 { return _y!=rhs._y || _x!=rhs._x; }
145         
146         //! Returns the squared magnitude of the vector
147         value_type mag_squared()const
148                 { return _x*_x+_y*_y; }
149         
150         //! Returns the magnitude of the vector
151         value_type mag()const
152                 { return sqrt(mag_squared()); }
153
154         //! Returns the reciprocal of the magnitude of the vector
155         value_type inv_mag()const
156                 { return 1.0/sqrt(mag_squared()); }
157
158         //! Returns a normalized version of the vector
159         Vector norm()const
160                 { return (*this)*inv_mag(); }
161
162         //! Returns a perpendicular version of the vector
163         Vector perp()const
164                 { return Vector(_y,-_x); }
165                 
166         bool is_equal_to(const Vector& rhs)const
167         {
168                 static const value_type epsilon(0.0000000000001);
169 //              return (_x>rhs._x)?_x-rhs._x<=epsilon:rhs._x-_x<=epsilon && (_y>rhs._y)?_y-rhs._y<=epsilon:rhs._y-_y<=epsilon;
170                 return (*this-rhs).mag_squared()<=epsilon;
171         }
172         
173         static const Vector zero() { return Vector(0,0); }
174 };
175
176 /*!     \typedef Point
177 **      \todo writeme
178 */
179 typedef Vector Point;
180
181
182
183 }; // END of namespace sinfg
184
185 namespace std {
186
187 inline sinfg::Vector::value_type
188 abs(const sinfg::Vector &rhs)
189         { return rhs.mag(); }
190
191 }; // END of namespace std
192
193 #include <ETL/bezier>
194
195 _ETL_BEGIN_NAMESPACE
196
197 template <>
198 class bezier_base<sinfg::Vector,float> : public std::unary_function<float,sinfg::Vector>
199 {
200 public:
201         typedef sinfg::Vector value_type;
202         typedef float time_type;
203 private:
204
205         bezier_base<sinfg::Vector::value_type,time_type> bezier_x,bezier_y;
206
207         value_type a,b,c,d;
208
209 protected:
210         affine_combo<value_type,time_type> affine_func; 
211
212 public:
213         bezier_base() { }
214         bezier_base(
215                 const value_type &a, const value_type &b, const value_type &c, const value_type &d,
216                 const time_type &r=0.0, const time_type &s=1.0):
217                 a(a),b(b),c(c),d(d) { set_rs(r,s); sync(); }
218                 
219         void sync()
220         {
221                 bezier_x[0]=a[0],bezier_y[0]=a[1];
222                 bezier_x[1]=b[0],bezier_y[1]=b[1];
223                 bezier_x[2]=c[0],bezier_y[2]=c[1];
224                 bezier_x[3]=d[0],bezier_y[3]=d[1];
225                 bezier_x.sync();
226                 bezier_y.sync();
227         }
228
229         value_type
230         operator()(time_type t)const
231         {
232                 return sinfg::Vector(bezier_x(t),bezier_y(t));
233         }
234         
235         void evaluate(time_type t, value_type &f, value_type &df) const
236         {
237                 t=(t-get_r())/get_dt();
238                 
239                 const value_type p1 = affine_func(
240                                                         affine_func(a,b,t),
241                                                         affine_func(b,c,t)
242                                                         ,t);
243                 const value_type p2 = affine_func(
244                                                         affine_func(b,c,t),
245                                                         affine_func(c,d,t)
246                                                 ,t);
247                 
248                 f = affine_func(p1,p2,t);
249                 df = (p2-p1)*3;
250         }
251
252         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); }
253         void set_r(time_type new_r) { bezier_x.set_r(new_r); bezier_y.set_r(new_r); }
254         void set_s(time_type new_s) { bezier_x.set_s(new_s); bezier_y.set_s(new_s); }
255         const time_type &get_r()const { return bezier_x.get_r(); }
256         const time_type &get_s()const { return bezier_x.get_s(); }
257         time_type get_dt()const { return bezier_x.get_dt(); }
258
259         value_type &
260         operator[](int i)
261         { return (&a)[i]; }
262
263         const value_type &
264         operator[](int i) const
265         { return (&a)[i]; }
266
267         //! Bezier curve intersection function
268         time_type intersect(const bezier_base<value_type,time_type> &x, time_type near=0.0)const
269         {
270                 return 0;
271         }
272 };
273
274 _ETL_END_NAMESPACE
275
276
277 /* === E N D =============================================================== */
278
279 #endif