00001 #include <stdio.h>
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef __ETL_ANGLE_H
00030 #define __ETL_ANGLE_H
00031
00032
00033
00034 #include <cmath>
00035 #include <functional>
00036
00037
00038
00039 #ifndef PI
00040 # define PI (3.1415926535897932384626433832795029L)
00041 # define HALF_PI (PI/2)
00042 #endif
00043
00044 #define ANGLE_EPSILON (1.0e-6)
00045
00046
00047
00048
00049
00050 _ETL_BEGIN_NAMESPACE
00051
00052
00058 class angle
00059 {
00060 public:
00061 typedef float value_type;
00062
00063 protected:
00064 typedef value_type unit;
00065
00066 unit v;
00067
00068 public:
00069
00070
00071
00072
00073
00074 const angle &
00075 operator+=(const angle &rhs)
00076 { v+=rhs.v; return *this; }
00077
00078 const angle &
00079 operator-=(const angle &rhs)
00080 { v-=rhs.v; return *this; }
00081
00082 const angle &
00083 operator*=(const unit &rhs)
00084 { v*=rhs; return *this; }
00085
00086 const angle &
00087 operator/=(const unit &rhs)
00088 { v/=rhs; return *this; }
00089
00091 angle
00092 operator+(const angle &rhs)const
00093 { return angle(*this)+=rhs; }
00094
00096
00097 angle
00098 operator-(const angle &rhs)const
00099 { return angle(*this)-=rhs; }
00100
00102
00104 angle
00105 operator*(const unit &rhs)const
00106 { return angle(*this)*=rhs; }
00107
00108 angle
00109 operator/(const unit &rhs)const
00110 { return angle(*this)/=rhs; }
00111
00113 angle
00114 operator-()const
00115 {
00116 angle ret;
00117 ret.v=-v;
00118 return ret;
00119 }
00120
00122
00125 angle
00126 operator~()const
00127 {
00128 angle ret;
00129 ret.v = v+PI;
00130 return ret.mod();
00131 }
00132
00136 bool
00137 operator<(const angle &rhs)const
00138 { return dist(rhs).v<(value_type)0.0; }
00139
00143 bool
00144 operator>(const angle &rhs)const
00145 { return dist(rhs).v>(value_type)0.0; }
00146
00152 bool
00153 operator<=(const angle &rhs)const
00154 { return dist(rhs).v<=(value_type)0.0; }
00155
00161 bool
00162 operator>=(const angle &rhs)const
00163 { return dist(rhs).v>=(value_type)0.0; }
00164
00168 bool
00169 operator==(const angle &rhs)const
00170 { return std::abs(dist(rhs).v)<ANGLE_EPSILON; }
00171
00175 bool
00176 operator!=(const angle &rhs)const
00177 { return std::abs(dist(rhs).v)>ANGLE_EPSILON; }
00178
00180
00182 angle
00183 abs()const
00184 {
00185 angle ret;
00186 ret.v=std::abs(v);
00187 return ret;
00188 }
00189
00191
00195 angle
00196 dist(const angle &rhs)const
00197 {
00198 angle ret;
00199 ret.v=v-rhs.v;
00200 ret.v-=rot_floor(ret.v+PI);
00201 return ret;
00202 }
00203
00205
00207 angle
00208 mod()const
00209 {
00210 angle ret(*this);
00211 ret.v-=rot_floor(ret.v);
00212 return ret;
00213 }
00214
00216 static angle
00217 zero()
00218 {
00219 angle ret;
00220 ret.v=0;
00221 return ret;
00222 }
00223
00225 static angle
00226 one()
00227 {
00228 angle ret;
00229 ret.v=PI*2;
00230 return ret;
00231 }
00232
00234 static angle
00235 half()
00236 {
00237 angle ret;
00238 ret.v=PI;
00239 return ret;
00240 }
00241
00242 bool operator!()const { return std::abs(mod().v) < ANGLE_EPSILON; }
00243
00244 private:
00245
00246 static value_type rot_floor(value_type x)
00247 { return static_cast<value_type>(std::floor(x/(PI*2))*PI*2); }
00248
00249 public:
00250
00251
00252
00253
00254 class rad;
00255 class deg;
00256 class rot;
00257
00258
00259
00260
00261
00262 class sin;
00263 class cos;
00264 class tan;
00265
00266
00267
00268
00269
00270 friend class rad;
00271 friend class deg;
00272 friend class rot;
00273 friend class sin;
00274 friend class cos;
00275 friend class tan;
00276
00277
00278
00279
00280
00281 #ifndef ETL_NO_DEPRECATED
00282 typedef rad radians;
00283 typedef deg degrees;
00284 typedef rot rotations;
00285 #endif
00286 };
00287
00288
00294 class angle::rad : public angle
00295 {
00296 public:
00297 explicit rad(const value_type &x) { v=x; }
00298 rad(const angle &a):angle(a) { }
00299 rad mod()const { return angle::mod(); }
00300 rad dist(const angle &rhs)const { return angle::dist(rhs); }
00301 value_type get()const { return v; }
00302 #ifndef ETL_NO_DEPRECATED
00303
00304 #endif
00305 };
00306
00307
00308
00314 class angle::deg : public angle
00315 {
00316 public:
00317 explicit deg(const value_type &x) { v=x*((PI*2)/360); }
00318 deg(const angle &a):angle(a) { }
00319 deg mod()const { return angle::mod(); }
00320 deg dist(const angle &rhs)const { return angle::dist(rhs); }
00321 value_type get()const { return v*360/(PI*2); }
00322 #ifndef ETL_NO_DEPRECATED
00323
00324 #endif
00325 };
00326
00327
00328
00334 class angle::rot : public angle
00335 {
00336 public:
00337 explicit rot(const value_type &x) { v=x*(PI*2); }
00338 rot(const angle &a):angle(a) { }
00339 rot mod()const { return angle::mod(); }
00340 rot dist(const angle &rhs)const { return angle::dist(rhs); }
00341 value_type get()const { return v/(PI*2); }
00342 #ifndef ETL_NO_DEPRECATED
00343
00344 #endif
00345 };
00346
00347
00348
00354 class angle::sin : public angle
00355 {
00356 public:
00357 explicit sin(const value_type &x) { v=static_cast<value_type>(std::asin(x)); }
00358 sin(const angle &a):angle(a) { }
00359 sin mod()const { return angle::mod(); }
00360 sin dist(const angle &rhs)const { return angle::dist(rhs); }
00361 value_type get()const { return static_cast<value_type>(std::sin(v)); }
00362 #ifndef ETL_NO_DEPRECATED
00363
00364 #endif
00365 };
00366
00367
00368
00374 class angle::cos : public angle
00375 {
00376 public:
00377 explicit cos(const value_type &x) { v=(value_type)(std::acos(x)); }
00378 cos(const angle &a):angle(a) { }
00379 cos mod()const { return angle::mod(); }
00380 cos dist(const angle &rhs)const { return angle::dist(rhs); }
00381 value_type get()const { return (value_type)std::cos(v); }
00382 #ifndef ETL_NO_DEPRECATED
00383
00384 #endif
00385 };
00386
00387
00388
00394 class angle::tan : public angle
00395 {
00396 public:
00397 explicit tan(const value_type &x) { v=(value_type)(std::atan(x)); }
00398 tan(const value_type &y,const value_type &x) { v=(value_type)(std::atan2(y,x)); }
00399 tan(const angle &a):angle(a) { }
00400 tan mod()const { return angle::mod(); }
00401 tan dist(const angle &rhs)const { return angle::dist(rhs); }
00402 value_type get()const { return (value_type)std::tan(v); }
00403 #ifndef ETL_NO_DEPRECATED
00404
00405 #endif
00406 };
00407
00408
00409 _ETL_END_NAMESPACE
00410
00411
00412
00413 template <typename T>
00414 struct affine_combo<etl::angle, T>
00415 {
00416 typedef T time_type;
00417
00418
00419
00420
00421 etl::angle operator()(const etl::angle &a,const etl::angle &b,const time_type &t)const
00422 {
00423 return b.dist(a)*(float)t+a;
00424 }
00425
00426 etl::angle reverse(const etl::angle &x, const etl::angle &b, const time_type &t)const
00427 {
00428 return x.dist(b*(float)t)*(float)(time_type(1)/(time_type(1)-t));
00429 }
00430 };
00431
00432 template <>
00433 struct distance_func<etl::angle> : public std::binary_function<etl::angle, etl::angle, etl::angle>
00434 {
00435 etl::angle operator()(const etl::angle &a,const etl::angle &b)const
00436 {
00437 etl::angle delta=b.dist(a);
00438
00439
00440 return delta;
00441 }
00442
00443 etl::angle cook(const etl::angle &x)const { return x; }
00444 etl::angle uncook(const etl::angle &x)const { return x; }
00445 };
00446
00447
00448
00449 #endif