Commented out the deprecated angle type conversion operators. They weren't used...
[synfig.git] / ETL / trunk / ETL / _angle.h
1 #include <stdio.h>
2 /* ========================================================================
3 ** Extended Template and Library
4 ** Angle Abstraction Class Implementation
5 ** $Id$
6 **
7 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
8 **
9 ** This package is free software; you can redistribute it and/or
10 ** modify it under the terms of the GNU General Public License as
11 ** published by the Free Software Foundation; either version 2 of
12 ** the License, or (at your option) any later version.
13 **
14 ** This package is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 ** General Public License for more details.
18 **
19 ** === N O T E S ===========================================================
20 **
21 ** This is an internal header file, included by other ETL headers.
22 ** You should not attempt to use it directly.
23 **
24 ** ========================================================================= */
25
26 /* === S T A R T =========================================================== */
27
28 #ifndef __ETL_ANGLE_H
29 #define __ETL_ANGLE_H
30
31 /* === H E A D E R S ======================================================= */
32
33 #include <cmath>
34 #include <functional>
35
36 /* === M A C R O S ========================================================= */
37
38 #ifndef PI
39 # define PI (3.1415926535897932384626433832795029L)
40 # define HALF_PI (PI/2)
41 #endif
42
43 /* === T Y P E D E F S ===================================================== */
44
45 /* === C L A S S E S & S T R U C T S ======================================= */
46
47 _ETL_BEGIN_NAMESPACE
48
49 // ========================================================================
50 /*!     \class  angle   _angle.h        ETL/angle
51 **      \brief  Abstraction of the concept of an angle
52 **  \see angle::deg, angle::rad, angle::rot, angle::sin, angle::cos, angle::tan, fastangle
53 **      \writeme
54 */
55 class angle
56 {
57 public:
58         typedef float value_type;
59
60 protected:
61         typedef value_type unit;
62
63         unit v; //! Stored in radians; positive values indicate counter-clockwise.
64
65 public:
66
67         /*
68         ** Arithmetic Operators
69         */
70
71         const angle     &
72         operator+=(const angle &rhs)
73         { v+=rhs.v; return *this; }
74
75         const angle     &
76         operator-=(const angle &rhs)
77         { v-=rhs.v; return *this; }
78
79         const angle     &
80         operator*=(const unit &rhs)
81         { v*=rhs; return *this; }
82
83         const angle     &
84         operator/=(const unit &rhs)
85         { v/=rhs; return *this; }
86
87         //! Angle Addition Operator
88         angle
89         operator+(const angle &rhs)const
90         { return angle(*this)+=rhs; }
91
92         //! Angle Subtraction Operator
93         /*! \sa angle dist(const angle &) */
94         angle
95         operator-(const angle &rhs)const
96         { return angle(*this)-=rhs; }
97
98         //! Angle Scalar Multiplication Operator
99         /*! This operator will multiply the given
100                 angle by the given scalar value. */
101         angle
102         operator*(const unit &rhs)const
103         { return angle(*this)*=rhs; }
104
105         angle
106         operator/(const unit &rhs)const
107         { return angle(*this)/=rhs; }
108
109         //! Angle Negation
110         angle
111         operator-()const
112         {
113                 angle ret;
114                 ret.v=-v;
115                 return ret;
116         }
117
118         //! 180 degree rotation operator
119         /*! Returns the angle directly opposite of
120                 the given angle, and will yield a result
121                 between 0 and 2PI */
122         angle
123         operator~()const
124         {
125                 angle ret;
126                 ret.v = v+PI;
127                 return ret.mod();
128         }
129
130         /*! Returns true if the shortest
131                 angle from the left-hand to the
132                 right-hand side is counter-clockwise */
133         bool
134         operator<(const angle &rhs)const
135         { return dist(rhs).v<(value_type)0.0; }
136
137         /*! Returns true if the shortest
138                 angle from the left-hand to the
139                 right-hand side is clockwise */
140         bool
141         operator>(const angle &rhs)const
142         { return dist(rhs).v>(value_type)0.0; }
143
144         /*! Returns true if the shortest
145                 angle from the left-hand to the
146                 right-hand side is counter-clockwise,
147                 or if the angles are refer to the same
148                 point on the unit circle. */
149         bool
150         operator<=(const angle &rhs)const
151         { return dist(rhs).v<=(value_type)0.0; }
152
153         /*! Returns true if the shortest
154                 angle from the left-hand to the
155                 right-hand side is clockwise,
156                 or if the angles are refer to the same
157                 point on the unit circle. */
158         bool
159         operator>=(const angle &rhs)const
160         { return dist(rhs).v>=(value_type)0.0; }
161
162         /*! Returns true if the angles
163                 are refer to the same point
164                 on the unit circle. */
165         bool
166         operator==(const angle &rhs)const
167         { return std::abs(dist(rhs).v)<epsilon; }
168
169         /*! Returns false if the angles
170                 are refer to the same point
171                 on the unit circle. */
172         bool
173         operator!=(const angle &rhs)const
174         { return std::abs(dist(rhs).v)>epsilon; }
175
176         //! Angle Difference Function
177         /*! This function will return the
178                 shortest physical distance between
179                 two angles, from -PI/2 to PI/2
180                 \sa angle operator-(const angle &) */
181         angle
182         dist(const angle &rhs)const
183         {
184                 angle ret;
185                 ret.v=v-rhs.v;
186                 ret.v-=rot_floor(ret.v+PI);
187                 return ret;
188         }
189
190         //! Rotation Modulus
191         /*! This function will return the
192                 value of the angle between 0 and 2PI */
193         angle
194         mod()const
195         {
196                 angle ret(*this);
197                 ret.v-=rot_floor(ret.v);
198                 return ret;
199         }
200
201         //! Zero Rotation (0 degrees)
202         static angle
203         zero()
204         {
205                 angle ret;
206                 ret.v=0;
207                 return ret;
208         }
209
210         //! One Complete Rotation (360 degrees)
211         static angle
212         one()
213         {
214                 angle ret;
215                 ret.v=PI*2;
216                 return ret;
217         }
218
219         //! One Half Rotation (180 degrees)
220         static angle
221         half()
222         {
223                 angle ret;
224                 ret.v=PI;
225                 return ret;
226         }
227
228         bool operator!()const { return std::abs(mod().v) < epsilon; }
229
230 private:
231
232         static value_type rot_floor(value_type x)
233         { return static_cast<value_type>(std::floor(x/(PI*2))*PI*2); }
234
235         static const value_type epsilon = 1.0e-6;
236
237 public:
238         /*
239         ** Conversion Classes
240         */
241
242         class rad;
243         class deg;
244         class rot;
245
246         /*
247         ** Trigonometric Classes
248         */
249
250         class sin;
251         class cos;
252         class tan;
253
254         /*
255         ** Friend classes
256         */
257
258         friend class rad;
259         friend class deg;
260         friend class rot;
261         friend class sin;
262         friend class cos;
263         friend class tan;
264
265         /*
266         ** Deprecated
267         */
268
269 #ifndef ETL_NO_DEPRECATED
270         typedef rad             radians;
271         typedef deg             degrees;
272         typedef rot             rotations;
273 #endif
274 }; // END of class angle
275
276 // ========================================================================
277 /*!     \class  angle::rad      _angle.h        ETL/angle
278 **      \brief  Angle representation in radians
279 **      \see angle
280 **      \writeme
281 */
282 class angle::rad : public angle
283 {
284 public:
285         explicit rad(const value_type &x) { v=x; }
286         rad(const angle &a):angle(a) { }
287         rad     mod()const { return angle::mod(); }
288         rad dist(const angle &rhs)const { return angle::dist(rhs); }
289         value_type get()const { return v; }
290 #ifndef ETL_NO_DEPRECATED
291         // operator value_type()const ETL_DEPRECATED_FUNCTION;
292 #endif
293 }; // END of class angle::radians
294 // inline angle::rad::operator angle::value_type()const { return get(); }
295
296 // ========================================================================
297 /*!     \class  angle::deg      _angle.h        ETL/angle
298 **      \brief  Angle representation in degrees
299 **      \see angle
300 **      \writeme
301 */
302 class angle::deg : public angle
303 {
304 public:
305         explicit deg(const value_type &x) { v=x*((PI*2)/360); }
306         deg(const angle &a):angle(a) { }
307         deg     mod()const { return angle::mod(); }
308         deg dist(const angle &rhs)const { return angle::dist(rhs); }
309         value_type get()const { return v*360/(PI*2); }
310 #ifndef ETL_NO_DEPRECATED
311         // operator value_type()const ETL_DEPRECATED_FUNCTION;
312 #endif
313 }; // END of class angle::degrees
314 // inline angle::deg::operator angle::value_type()const { return get(); }
315
316 // ========================================================================
317 /*!     \class  angle::rot      _angle.h        ETL/angle
318 **      \brief  Angle representation in rotations
319 **      \see angle
320 **      \writeme
321 */
322 class angle::rot : public angle
323 {
324 public:
325         explicit rot(const value_type &x) { v=x*(PI*2); }
326         rot(const angle &a):angle(a) { }
327         rot mod()const { return angle::mod(); }
328         rot dist(const angle &rhs)const { return angle::dist(rhs); }
329         value_type get()const { return v/(PI*2); }
330 #ifndef ETL_NO_DEPRECATED
331         // operator value_type()const ETL_DEPRECATED_FUNCTION;
332 #endif
333 }; // END of class angle::rotations
334 // inline angle::rot::operator angle::value_type()const { return get(); }
335
336 // ========================================================================
337 /*!     \class  angle::sin      _angle.h        ETL/angle
338 **      \brief  Angle representation as a sine function
339 **      \see angle
340 **      \writeme
341 */
342 class angle::sin : public angle
343 {
344 public:
345         explicit sin(const value_type &x) { v=static_cast<value_type>(std::asin(x)); }
346         sin(const angle &a):angle(a) { }
347         sin     mod()const { return angle::mod(); }
348         sin dist(const angle &rhs)const { return angle::dist(rhs); }
349         value_type get()const { return static_cast<value_type>(std::sin(v)); }
350 #ifndef ETL_NO_DEPRECATED
351         // operator value_type()const ETL_DEPRECATED_FUNCTION;
352 #endif
353 }; // END of class angle::sin
354 // inline angle::sin::operator angle::value_type()const { return get(); }
355
356 // ========================================================================
357 /*!     \class  angle::cos      _angle.h        ETL/angle
358 **      \brief  Angle representation as a cosine function
359 **      \see angle
360 **      \writeme
361 */
362 class angle::cos : public angle
363 {
364 public:
365         explicit cos(const value_type &x)       { v=(value_type)(std::acos(x)); }
366         cos(const angle &a):angle(a) { }
367         cos     mod()const { return angle::mod(); }
368         cos dist(const angle &rhs)const { return angle::dist(rhs); }
369         value_type get()const { return (value_type)std::cos(v); }
370 #ifndef ETL_NO_DEPRECATED
371         // operator value_type()const ETL_DEPRECATED_FUNCTION;
372 #endif
373 }; // END of class angle::cos
374 // inline angle::cos::operator angle::value_type()const { return get(); }
375
376 // ========================================================================
377 /*!     \class  angle::tan      _angle.h        ETL/angle
378 **      \brief  Angle representation as a tangent function
379 **      \see angle
380 **      \writeme
381 */
382 class angle::tan : public angle
383 {
384 public:
385         explicit tan(const value_type &x)       { v=(value_type)(std::atan(x)); }
386         tan(const value_type &y,const value_type &x) { v=(value_type)(std::atan2(y,x)); }
387         tan(const angle &a):angle(a) { }
388         tan     mod()const { return angle::mod(); }
389         tan dist(const angle &rhs)const { return angle::dist(rhs); }
390         value_type get()const { return (value_type)std::tan(v); }
391 #ifndef ETL_NO_DEPRECATED
392         // operator value_type()const ETL_DEPRECATED_FUNCTION;
393 #endif
394 }; // END of class angle::tan
395 // inline angle::tan::operator angle::value_type()const { return get(); }
396
397 _ETL_END_NAMESPACE
398
399 //#include <iostream>
400
401 template <typename T>
402 struct affine_combo<etl::angle, T>
403 {
404         typedef T time_type;
405
406         //affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was created!"<<std::endl; }
407         //~affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was DELETED!"<<std::endl; }
408
409         etl::angle operator()(const etl::angle &a,const etl::angle &b,const time_type &t)const
410         {
411                 return b.dist(a)*(float)t+a;
412         }
413
414         etl::angle reverse(const etl::angle &x, const etl::angle &b, const time_type &t)const
415         {
416                 return x.dist(b*(float)t)*(float)(time_type(1)/(time_type(1)-t));
417         }
418 };
419
420 template <>
421 struct distance_func<etl::angle> : public std::binary_function<etl::angle, etl::angle, etl::angle>
422 {
423         etl::angle operator()(const etl::angle &a,const etl::angle &b)const
424         {
425                 etl::angle delta=b.dist(a);
426                 //if(delta<etl::angle::zero())
427                 //      return delta+etl::angle::one();
428                 return delta;
429         }
430
431         etl::angle cook(const etl::angle &x)const { return x; }
432         etl::angle uncook(const etl::angle &x)const { return x; }
433 };
434
435 /* === E N D =============================================================== */
436
437 #endif