ETL  0.04.19
_fastangle.h
Go to the documentation of this file.
1 
25 /* === S T A R T =========================================================== */
26 
27 #ifndef __ETL__FASTANGLE_H
28 #define __ETL__FASTANGLE_H
29 
30 /* === H E A D E R S ======================================================= */
31 
32 #include <cmath>
33 #include <ETL/fixed>
34 
35 #include "_fastangle_tables.h"
36 
37 /* === M A C R O S ========================================================= */
38 
39 #ifndef PI
40 # define PI (3.1415926535897932384626433832795029L)
41 #endif
42 
43 #define ETL_FASTANGLE_INIT()
44 
45 /* === T Y P E D E F S ===================================================== */
46 
47 /* === C L A S S E S & S T R U C T S ======================================= */
48 
50 
57 class fastangle
58 {
59 public:
60  typedef double value_type;
61 
62 protected:
64 
65  unit v;
66 
67 public:
68 
69  /*
70  ** Arithmetic Operators
71  */
72 
74  fastangle
75  operator+(const fastangle &rhs)const
76  {
77  fastangle ret;
78  ret.v=v+rhs.v;
79  return ret;
80  }
81 
83 
84  fastangle
85  operator-(const fastangle &rhs)const
86  {
87  fastangle ret;
88  ret.v=v-rhs.v;
89  return ret;
90  }
91 
93 
95  fastangle
96  operator*(const unit &rhs)const
97  {
98  fastangle ret;
99  ret.v=v*rhs;
100  return ret;
101  }
102 
103  fastangle
104  operator/(const unit &rhs)const
105  {
106  fastangle ret;
107  ret.v=v/rhs;
108  return ret;
109  }
110 
111  const fastangle &
112  operator+=(const fastangle &rhs)
113  {
114  v+=rhs.v;
115  return *this;
116  }
117 
118  const fastangle &
119  operator-=(const fastangle &rhs)
120  {
121  v-=rhs.v;
122  return *this;
123  }
124 
125  const fastangle &
126  operator*=(const unit &rhs)
127  {
128  v*=rhs;
129  return *this;
130  }
131 
132  const fastangle &
133  operator/=(const unit &rhs)
134  {
135  v/=rhs;
136  return *this;
137  }
138 
140  fastangle
141  operator-()const
142  {
143  fastangle ret;
144  ret.v=-v;
145  return ret;
146  }
147 
149 
152  fastangle
153  operator~()const
154  {
155  fastangle ret;
156  ret.v=(unit)std::floor(v+0.5f);
157  return ret;
158  }
159 
163  bool
164  operator<(const fastangle &rhs)const
165  { return v<rhs.v; }
166 // { return dist(rhs).v<(value_type)0.0; }
167 
171  bool
172  operator>(const fastangle &rhs)const
173  { return v>rhs.v; }
174 // { return dist(rhs).v>(value_type)0.0; }
175 
181  bool
182  operator<=(const fastangle &rhs)const
183  { return v<=rhs.v; }
184 // { return dist(rhs).v<=(value_type)0.0; }
185 
191  bool
192  operator>=(const fastangle &rhs)const
193  { return v>=rhs.v; }
194 // { return dist(rhs).v>=(value_type)0.0; }
195 
199  bool
200  operator==(const fastangle &rhs)const
201  { return v==rhs.v; }
202 // { return dist(rhs).v==(value_type)0.0; }
203 
207  bool
208  operator!=(const fastangle &rhs)const
209  { return v!=rhs.v; }
210 // { return dist(rhs).v!=(value_type)0.0; }
211 
213 
218  fastangle
219  dist(const fastangle &rhs)const
220  {
221  fastangle ret;
222  ret.v=v-rhs.v;
223  ret.v-=(unit)std::floor(ret.v+0.5f);
224  return ret;
225  }
226 
228 
230  fastangle
231  mod()const
232  {
233  fastangle ret(*this);
234  ret.v-=(unit)std::floor(ret.v);
235  return ret;
236  }
237 
238  static fastangle
240  {
241  fastangle ret;
242  ret.v=0;
243  return ret;
244  }
245 
246  bool operator!()const { return v==unit(0); }
247 
248  /*
249  ** Conversion Classes
250  */
251 
252  class radians;
253  class degrees;
254  class rotations;
255 
256  /*
257  ** Trigonometric Classes
258  */
259 
260  class sin;
261  class cos;
262  class tan;
263 
264  /*
265  ** Friend classes
266  */
267 
268  friend class radians;
269  friend class degrees;
270  friend class rotations;
271  friend class sin;
272  friend class cos;
273  friend class tan;
274 
275  /*
276  ** Bleh...
277  */
278 
279  typedef radians rad;
280  typedef degrees deg;
281  typedef rotations rot;
282 
283 }; // END of class fastangle
284 
292 {
293 public:
294  radians(const value_type &x) { v=x/((value_type)PI*2.0f); }
295  radians(const fastangle &a):fastangle(a) { }
296  radians mod()const { return fastangle::mod(); }
297  radians dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
298  operator value_type()const { return get(); }
299  value_type get()const { return (value_type)v*(value_type)PI*2.0f; }
300 }; // END of class fastangle::radians
301 
309 {
310 public:
311  degrees(const value_type &x) { v=x/360; }
312  degrees(const fastangle &a):fastangle(a) { }
313  degrees mod()const { return fastangle::mod(); }
314  degrees dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
315  operator value_type()const { return get(); }
316  value_type get()const { return v*360/*(value_type)(v-::floor(v))*360*/; }
317 }; // END of class fastangle::degrees
318 
326 {
327 public:
328  rotations(const value_type &x) { v=x; }
329  rotations(const fastangle &a):fastangle(a) { }
330  rotations mod()const { return fastangle::mod(); }
331  rotations dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
332  operator value_type()const { return get(); }
333  value_type get()const { return v; }
334 }; // END of class fastangle::rotations
335 
342 class fastangle::sin : public fastangle
343 {
344 public:
346  sin(const fastangle &a):fastangle(a) { }
347  sin mod()const { return fastangle::mod(); }
348  sin dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
349  operator value_type()const { return get(); }
351 }; // END of class fastangle::sin
352 
359 class fastangle::cos : public fastangle
360 {
361 public:
363  cos(const fastangle &a):fastangle(a) { }
364  cos mod()const { return fastangle::mod(); }
365  cos dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
366  operator value_type()const { return get(); }
368 }; // END of class fastangle::cos
369 
376 class fastangle::tan : public fastangle
377 {
378 public:
379  tan(const value_type &x)
380  {
381  if(x>1)
382  v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((1.0/x)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
383  else if(x<-1)
384  v.data()=-(1<<(ETL_FASTANGLE_LOOKUP_RES-1)) + (1<<(ETL_FASTANGLE_LOOKUP_RES-2)) - _fastangle_atan_table[(int)(((1.0/x)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
385  else
386  v.data()=_fastangle_atan_table[(int)((x+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
387  }
388 
389  tan(const value_type &y,const value_type &x)
390  {
391  if(x>=0 && y>=0) // First quadrant
392  {
393  if(y>x)
394  v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((x/y)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
395  else
396  v.data()=_fastangle_atan_table[(int)(((y/x)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
397  }
398  else if(x>=0 && y<0) // Fourth quadrant
399  {
400  if(-y>x)
402  else
403  v.data()=_fastangle_atan_table[(int)(((y/x)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
404  }
405  else if(x<0 && y>=0) // Second quadrant
406  {
407  if(y>-x)
408  v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((x/y)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
409  else
410  v.data()=_fastangle_atan_table[(int)(((y/x)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))]+(1<<(ETL_FASTANGLE_LOOKUP_RES-1));
411  }
412  else if(x<0 && y<0) // Third Quadrant
413  {
414  if(-y>-x)
416  else
417  v.data()=_fastangle_atan_table[(int)(((y/x)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))]-(1<<(ETL_FASTANGLE_LOOKUP_RES-1));
418  }
419  else v.data()=0;
420  }
421  tan(const fastangle &a):fastangle(a) { }
422  tan mod()const { return fastangle::mod(); }
423  tan dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
424  operator value_type()const { return get(); }
426 }; // END of class fastangle::tan
427 
429 
430 template <>
431 struct affine_combo<etl::fastangle,float>
432 {
433  etl::fastangle operator()(const etl::fastangle &a,const etl::fastangle &b,const float &t)const
434  {
435  return b.dist(a)*t+a;
436  }
437 
438  etl::fastangle reverse(const etl::fastangle &x, const etl::fastangle &b, const float &t)const
439  {
440  return x.dist(b*t)*((float)1/((float)1-t));
441  }
442 };
443 
444 template <>
445 struct distance_func<etl::fastangle> : public std::binary_function<etl::fastangle, etl::fastangle, etl::fastangle>
446 {
447  etl::fastangle operator()(const etl::fastangle &a,const etl::fastangle &b)const
448  {
449  etl::fastangle delta=b.dist(a);
450  if(delta<etl::fastangle::zero())
451  return -delta;
452  return delta;
453  }
454 
455  etl::fastangle cook(const etl::fastangle &x) { return x; }
456  etl::fastangle uncook(const etl::fastangle &x) { return x; }
457 };
458 
459 /* === E N D =============================================================== */
460 
461 #endif