00001 #ifndef _ANIMAL_ROTATION_2D_
00002 #define _ANIMAL_ROTATION_2D_
00003
00004 #include <iostream>
00005 #include <animal/array.h>
00006
00007 #include <cmath>
00008
00009 namespace animal {
00010
00011
00012 template < class Real = double > class Rotation2d_Traits;
00013
00014
00015
00016
00017
00023
00024
00025 template
00026 <
00027 class RealT = double,
00028 class TraitsT = Rotation2d_Traits<RealT>
00029 >
00030 class Rotation2d
00031 {
00032 public:
00033
00036
00038 typedef TraitsT Traits;
00039
00041 typedef RealT Real;
00042
00044
00045
00048
00049 Rotation2d(){}
00050
00052 Rotation2d( const Real angle )
00053 {
00054 _matrix[0][0] = cos(angle);
00055 _matrix[0][1] = sin(angle);
00056 _matrix[1][0] = -_matrix[0][1];
00057 _matrix[1][1] = _matrix[0][0];
00058 }
00059
00061 static Rotation2d identity() { return Rotation2d( 1, 0, 0, 1 ); }
00062
00064
00067
00069 Real angle() const {
00070 return _matrix[0][1] > 0 ?
00071 acos
00072 ( _matrix[0][0] > 1 ? 1 : _matrix[0][0] < -1 ? -1 : _matrix[0][0] )
00073 :
00074 -acos
00075 ( _matrix[0][0] > 1 ? 1 : _matrix[0][0] < -1 ? -1 : _matrix[0][0] )
00076 ;
00077 }
00078
00080 Rotation2d& setAngle( const Real angle )
00081 {
00082 _matrix[0][0] = cos(angle);
00083 _matrix[0][1] = sin(angle);
00084 _matrix[1][0] = - _matrix[0][1];
00085 _matrix[1][1] = _matrix[0][0];
00086 return (*this);
00087 }
00088
00090 Rotation2d inverse() const
00091 {
00092 return Rotation2d(
00093 _matrix[0][0], _matrix[1][0],
00094 _matrix[0][1], _matrix[1][1]
00095 );
00096 }
00097
00099 Rotation2d operator * ( const Real u ) const
00100 {
00101 return Rotation2d
00102 (
00103 angle() * u
00104 );
00105 }
00106
00108
00109
00112
00114 Rotation2d operator * ( const Rotation2d& r ) const
00115 {
00116 return Rotation2d(
00117 _matrix[0][0] * r._matrix[0][0] + _matrix[0][1] * r._matrix[1][0],
00118 _matrix[0][0] * r._matrix[0][1] + _matrix[0][1] * r._matrix[1][1],
00119 _matrix[1][0] * r._matrix[0][0] + _matrix[1][1] * r._matrix[1][0],
00120 _matrix[1][0] * r._matrix[0][1] + _matrix[1][1] * r._matrix[1][1]
00121 );
00122 }
00123
00125 Rotation2d& operator *= ( const Rotation2d& r )
00126 {
00127 (*this) = Rotation2d(
00128 _matrix[0][0] * r._matrix[0][0] + _matrix[0][1] * r._matrix[1][0],
00129 _matrix[0][0] * r._matrix[0][1] + _matrix[0][1] * r._matrix[1][1],
00130 _matrix[1][0] * r._matrix[0][0] + _matrix[1][1] * r._matrix[1][0],
00131 _matrix[1][0] * r._matrix[0][1] + _matrix[1][1] * r._matrix[1][1]
00132 );
00133 return (*this);
00134 }
00135
00137 Rotation2d operator / ( const Rotation2d& r ) const
00138 {
00139 return Rotation2d(
00140 _matrix[0][0] * r._matrix[0][0] + _matrix[0][1] * r._matrix[0][1],
00141 _matrix[0][0] * r._matrix[1][0] + _matrix[0][1] * r._matrix[1][1],
00142 _matrix[1][0] * r._matrix[0][0] + _matrix[1][1] * r._matrix[0][1],
00143 _matrix[1][0] * r._matrix[1][0] + _matrix[1][1] * r._matrix[1][1]
00144 );
00145 }
00146
00148 Rotation2d& operator /= ( const Rotation2d& r )
00149 {
00150 (*this) = Rotation2d(
00151 _matrix[0][0] * r._matrix[0][0] + _matrix[0][1] * r._matrix[0][1],
00152 _matrix[0][0] * r._matrix[1][0] + _matrix[0][1] * r._matrix[1][1],
00153 _matrix[1][0] * r._matrix[0][0] + _matrix[1][1] * r._matrix[0][1],
00154 _matrix[1][0] * r._matrix[1][0] + _matrix[1][1] * r._matrix[1][1]
00155 );
00156 return (*this);
00157 }
00158
00160
00163
00165 template< class RotationVelocity >
00166 static Rotation2d eulerIncrement( const RotationVelocity& omega, const double h )
00167 {
00168 return Rotation2d( h * omega );
00169 }
00170
00172
00174
00176 template< class R, class T, class Vector >
00177 friend Vector operator * ( const Vector&, const Rotation2d<R,T>& );
00178
00180 template< class R, class T, class Vector >
00181 friend Vector& operator *= ( Vector&, const Rotation2d<R,T>& );
00182
00184 template< class R, class T, class Vector >
00185 friend Vector operator / ( const Vector&, const Rotation2d<R,T>& );
00186
00188 template< class R, class T, class Vector >
00189 friend Vector& operator /= ( Vector&, const Rotation2d<R,T>& );
00190
00192
00195
00197 template< class R, class T >
00198 friend std::istream& operator >> ( std::istream&, Rotation2d<R,T>& );
00199
00201 template< class R, class T >
00202 friend std::ostream& operator << ( std::ostream&, const Rotation2d<R,T>& );
00203
00205
00206
00207 private:
00208
00210 Array<2 , Array< 2, Real> > _matrix;
00211
00213 Rotation2d( const Real xx, const Real xy, const Real yx, const Real yy )
00214 {
00215 _matrix[0][0] = xx; _matrix[0][1] = xy;
00216 _matrix[1][0] = yx; _matrix[1][1] = yy;
00217 }
00218
00219
00220 };
00224
00225
00228
00229
00231
00233 template< class R, class T, class Vector >
00234 inline Vector
00235 operator / (
00236 const Vector& v,
00237 const Rotation2d<R,T>& m
00238 )
00239 {
00240 return Vector(
00241 m._matrix[0][0] * T::x(v) + m._matrix[0][1] * T::y(v),
00242 m._matrix[1][0] * T::x(v) + m._matrix[1][1] * T::y(v)
00243 );
00244 }
00245
00247 template< class R, class T, class Vector >
00248 inline Vector&
00249 operator /= (
00250 Vector& v,
00251 const Rotation2d<R,T>& m
00252 )
00253 {
00254 v = Vector(
00255 m._matrix[0][0] * T::x(v) + m._matrix[0][1] * T::y(v),
00256 m._matrix[1][0] * T::x(v) + m._matrix[1][1] * T::y(v)
00257 );
00258 return v;
00259 }
00260
00262 template< class R, class T, class Vector >
00263 inline Vector
00264 operator * (
00265 const Vector& v,
00266 const Rotation2d<R,T>& m
00267 )
00268 {
00269 return Vector(
00270 m._matrix[0][0] * T::x(v) + m._matrix[1][0] * T::y(v),
00271 m._matrix[0][1] * T::x(v) + m._matrix[1][1] * T::y(v)
00272 );
00273 }
00274
00276 template< class R, class T, class Vector >
00277 inline Vector&
00278 operator *= (
00279 Vector& v,
00280 const Rotation2d<R,T>& m
00281 )
00282 {
00283 v = Vector(
00284 m._matrix[0][0] * T::x(v) + m._matrix[1][0] * T::y(v),
00285 m._matrix[0][1] * T::x(v) + m._matrix[1][1] * T::y(v)
00286 );
00287 return v;
00288 }
00289
00291 template< class R, class T >
00292 std::istream& operator >> (
00293 std::istream& stream,
00294 Rotation2d<R,T>& r
00295 )
00296 {
00297 R angle;
00298 stream >> angle;
00299 r.setAngle( angle );
00300 return stream;
00301 }
00302
00304 template< class R, class T >
00305 std::ostream& operator << (
00306 std::ostream& stream,
00307 const Rotation2d<R,T>& r
00308 )
00309 {
00310 stream << r.angle();
00311 return stream;
00312 }
00313
00315
00316
00317
00318
00319
00320
00326
00327
00328
00329
00330
00331 template <class Real>
00332 class Rotation2d_Traits
00333 {
00334 public:
00335
00338
00340 template< class Vector >
00341 static Real
00342 x( const Vector& v )
00343 {
00344 return v[0];
00345 }
00346
00348 template< class Vector >
00349 static Real
00350 y( const Vector& v )
00351 {
00352 return v[1];
00353 }
00354
00356
00357 };
00358
00359
00360 }
00361
00362 #endif