00001
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 #ifndef __ETL_ANGLE_H
00028 #define __ETL_ANGLE_H
00029
00030
00031
00032 #include <cmath>
00033 #include <functional>
00034
00035
00036
00037 #ifndef PI
00038 # define PI (3.1415926535897932384626433832795029L)
00039 # define HALF_PI (PI/2)
00040 #endif
00041
00042
00043
00044
00045
00046 _ETL_BEGIN_NAMESPACE
00047
00048
00054 class angle
00055 {
00056 public:
00057 typedef float value_type;
00058
00059 protected:
00060 typedef value_type unit;
00061
00062 unit v;
00063
00064 public:
00065
00066
00067
00068
00069
00070 const angle &
00071 operator+=(const angle &rhs)
00072 { v+=rhs.v; return *this; }
00073
00074 const angle &
00075 operator-=(const angle &rhs)
00076 { v-=rhs.v; return *this; }
00077
00078 const angle &
00079 operator*=(const unit &rhs)
00080 { v*=rhs; return *this; }
00081
00082 const angle &
00083 operator/=(const unit &rhs)
00084 { v/=rhs; return *this; }
00085
00087 angle
00088 operator+(const angle &rhs)const
00089 { return angle(*this)+=rhs; }
00090
00092
00093 angle
00094 operator-(const angle &rhs)const
00095 { return angle(*this)-=rhs; }
00096
00098
00100 angle
00101 operator*(const unit &rhs)const
00102 { return angle(*this)*=rhs; }
00103
00104 angle
00105 operator/(const unit &rhs)const
00106 { return angle(*this)/=rhs; }
00107
00109 angle
00110 operator-()const
00111 {
00112 angle ret;
00113 ret.v=-v;
00114 return ret;
00115 }
00116
00118
00121 angle
00122 operator~()const
00123 {
00124 angle ret;
00125 ret.v=(value_type)std::floor(v+0.5f);
00126 return ret;
00127 }
00128
00132 bool
00133 operator<(const angle &rhs)const
00134 { return v<rhs.v; }
00135
00136
00140 bool
00141 operator>(const angle &rhs)const
00142 { return v>rhs.v; }
00143
00144
00150 bool
00151 operator<=(const angle &rhs)const
00152 { return v<=rhs.v; }
00153
00154
00160 bool
00161 operator>=(const angle &rhs)const
00162 { return v>=rhs.v; }
00163
00164
00168 bool
00169 operator==(const angle &rhs)const
00170 { return v==rhs.v; }
00171
00172
00176 bool
00177 operator!=(const angle &rhs)const
00178 { return v!=rhs.v; }
00179
00180
00182
00186 angle
00187 dist(const angle &rhs)const
00188 {
00189 angle ret;
00190
00191 ret.v=v-rhs.v;
00192
00193 ret.v-=rot_floor(ret.v+PI);
00194
00195 return ret;
00196 }
00197
00199
00201 angle
00202 mod()const
00203 {
00204 angle ret(*this);
00205 ret.v-=rot_floor(ret.v);
00206 return ret;
00207 }
00208
00209 static angle
00210 zero()
00211 {
00212 angle ret;
00213 ret.v=0;
00214 return ret;
00215 }
00216
00217 static angle
00218 one()
00219 {
00220 angle ret;
00221 ret.v=PI;
00222 return ret;
00223 }
00224
00225 static angle
00226 half()
00227 {
00228 angle ret;
00229 ret.v=PI*0.5;
00230 return ret;
00231 }
00232
00233 bool operator!()const { return v==0; }
00234
00235 private:
00236
00237 static value_type rot_floor(value_type x)
00238 { return static_cast<value_type>(std::floor(x/(PI*2))*PI*2); }
00239
00240 public:
00241
00242
00243
00244
00245 class rad;
00246 class deg;
00247 class rot;
00248
00249
00250
00251
00252
00253 class sin;
00254 class cos;
00255 class tan;
00256
00257
00258
00259
00260
00261 friend class rad;
00262 friend class deg;
00263 friend class rot;
00264 friend class sin;
00265 friend class cos;
00266 friend class tan;
00267
00268
00269
00270
00271
00272 #ifndef ETL_NO_DEPRECATED
00273 typedef rad radians;
00274 typedef deg degrees;
00275 typedef rot rotations;
00276 #endif
00277 };
00278
00279
00285 class angle::rad : public angle
00286 {
00287 public:
00288 explicit rad(const value_type &x) { v=x; }
00289 rad(const angle &a):angle(a) { }
00290 rad mod()const { return angle::mod(); }
00291 rad dist(const angle &rhs)const { return angle::dist(rhs); }
00292 #ifndef ETL_NO_DEPRECATED
00293 operator value_type()const ETL_DEPRECATED_FUNCTION;
00294 #endif
00295 value_type get()const { return v; }
00296 };
00297 inline angle::rad::operator angle::value_type()const { return get(); }
00298
00299
00305 class angle::deg : public angle
00306 {
00307 public:
00308 explicit deg(const value_type &x) { v=x*((PI*2)/360); }
00309 deg(const angle &a):angle(a) { }
00310 deg mod()const { return angle::mod(); }
00311 deg dist(const angle &rhs)const { return angle::dist(rhs); }
00312 value_type get()const { return v*360/(PI*2); }
00313 #ifndef ETL_NO_DEPRECATED
00314 operator value_type()const ETL_DEPRECATED_FUNCTION;
00315 #endif
00316 };
00317 inline angle::deg::operator angle::value_type()const { return get(); }
00318
00319
00325 class angle::rot : public angle
00326 {
00327 public:
00328 explicit rot(const value_type &x) { v=x*(PI*2); }
00329 rot(const angle &a):angle(a) { }
00330 rot mod()const { return angle::mod(); }
00331 rot dist(const angle &rhs)const { return angle::dist(rhs); }
00332 value_type get()const { return v/(PI*2); }
00333 #ifndef ETL_NO_DEPRECATED
00334 operator value_type()const ETL_DEPRECATED_FUNCTION;
00335 #endif
00336 };
00337 inline angle::rot::operator angle::value_type()const { return get(); }
00338
00339
00345 class angle::sin : public angle
00346 {
00347 public:
00348 explicit sin(const value_type &x) { v=static_cast<value_type>(std::asin(x)); }
00349 sin(const angle &a):angle(a) { }
00350 sin mod()const { return angle::mod(); }
00351 sin dist(const angle &rhs)const { return angle::dist(rhs); }
00352 value_type get()const { return static_cast<value_type>(std::sin(v)); }
00353 #ifndef ETL_NO_DEPRECATED
00354 operator value_type()const ETL_DEPRECATED_FUNCTION;
00355 #endif
00356 };
00357 inline angle::sin::operator angle::value_type()const { return get(); }
00358
00359
00365 class angle::cos : public angle
00366 {
00367 public:
00368 explicit cos(const value_type &x) { v=(value_type)(std::acos(x)); }
00369 cos(const angle &a):angle(a) { }
00370 cos mod()const { return angle::mod(); }
00371 cos dist(const angle &rhs)const { return angle::dist(rhs); }
00372 operator value_type()const ETL_DEPRECATED_FUNCTION;
00373 #ifndef ETL_NO_DEPRECATED
00374 value_type get()const { return (value_type)std::cos(v); }
00375 #endif
00376 };
00377 inline angle::cos::operator angle::value_type()const { return get(); }
00378
00379
00385 class angle::tan : public angle
00386 {
00387 public:
00388 explicit tan(const value_type &x) { v=(value_type)(std::atan(x)); }
00389 tan(const value_type &y,const value_type &x) { v=(value_type)(std::atan2(y,x)); }
00390 tan(const angle &a):angle(a) { }
00391 tan mod()const { return angle::mod(); }
00392 tan dist(const angle &rhs)const { return angle::dist(rhs); }
00393 #ifndef ETL_NO_DEPRECATED
00394 operator value_type()const ETL_DEPRECATED_FUNCTION;
00395 #endif
00396 value_type get()const { return (value_type)std::tan(v); }
00397 };
00398 inline angle::tan::operator angle::value_type()const { return get(); }
00399
00400 _ETL_END_NAMESPACE
00401
00402
00403
00404 template <typename T>
00405 struct affine_combo<etl::angle, T>
00406 {
00407 typedef T time_type;
00408
00409
00410
00411
00412 etl::angle operator()(const etl::angle &a,const etl::angle &b,const time_type &t)const
00413 {
00414 return b.dist(a)*(float)t+a;
00415 }
00416
00417 etl::angle reverse(const etl::angle &x, const etl::angle &b, const time_type &t)const
00418 {
00419 return x.dist(b*(float)t)*(float)(time_type(1)/(time_type(1)-t));
00420 }
00421 };
00422
00423 template <>
00424 struct distance_func<etl::angle> : public std::binary_function<etl::angle, etl::angle, etl::angle>
00425 {
00426 etl::angle operator()(const etl::angle &a,const etl::angle &b)const
00427 {
00428 etl::angle delta=b.dist(a);
00429
00430
00431 return delta;
00432 }
00433
00434 etl::angle cook(const etl::angle &x)const { return x; }
00435 etl::angle uncook(const etl::angle &x)const { return x; }
00436 };
00437
00438
00439
00440
00441 #endif