snark
math/angle.h
1 // This file is part of snark, a generic and flexible library
2 // for robotics research.
3 //
4 // Copyright (C) 2011 The University of Sydney
5 //
6 // snark is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // snark is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 // for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with snark. If not, see <http://www.gnu.org/licenses/>.
18 
19 #ifndef SNARK_MATH_ANGLE_H_
20 #define SNARK_MATH_ANGLE_H_
21 
22 #include <comma/math/cyclic.h>
23 
24 namespace snark{ namespace math{
25 
27 struct degrees;
28 
30 struct radians
31 {
32  double value;
33  explicit radians( double d ) : value( d ) {}
34  radians( degrees d );
35 };
36 
38 struct degrees
39 {
40  double value;
41  explicit degrees( double d ) : value( d ) {}
42  degrees( radians r );
43 };
44 
48 template < typename T >
49 class angle : public comma::math::cyclic< T >
50 {
51  public:
53  angle() : comma::math::cyclic< T >( comma::math::interval< T >( 0, 360 ), 0 ) {}
54  angle( degrees d ) : comma::math::cyclic< T >( comma::math::interval< T >( 0, 360 ), static_cast< T >( d.value ) ) {}
55  angle( radians d ) : comma::math::cyclic< T >( comma::math::interval< T >( 0, 360 ), static_cast< T >( degrees( d ).value ) ) {}
56  angle( const angle& rhs ) : comma::math::cyclic< T >( rhs.interval(), rhs() ) {}
57 
59  T as_degrees() const { return comma::math::cyclic< T >::operator()(); }
60  double as_radians() const { return math::radians( degrees(comma::math::cyclic< T >::operator()()) ).value; }
61 
63  const angle& operator+=( const angle& rhs ) { comma::math::cyclic< T >::operator+=( rhs ); return *this; }
64  const angle& operator-=( const angle& rhs ) { comma::math::cyclic< T >::operator-=( rhs ); return *this; }
65  const angle& operator+=( T t ) { comma::math::cyclic< T >::operator+=( t ); return *this; }
66  const angle& operator-=( T t ) { comma::math::cyclic< T >::operator-=( t ); return *this; }
67  const angle& operator*=( T t ) { comma::math::cyclic< T >::operator=( comma::math::cyclic< T >::operator()() * t ); return *this; }
68  const angle& operator/=( T t ) { comma::math::cyclic< T >::operator=( comma::math::cyclic< T >::operator()() / t ); return *this; }
69  angle operator+( const angle& rhs ) const { angle a( *this ); a += rhs; return a; }
70  angle operator-( const angle& rhs ) const { angle a( *this ); a -= rhs; return a; }
71  angle operator+( T rhs ) const { angle a( *this ); a += rhs; return a; }
72  angle operator-( T rhs ) const { angle a( *this ); a -= rhs; return a; }
73  angle operator*( T rhs ) const { angle a( *this ); a *= rhs; return a; }
74  angle operator/( T rhs ) const { angle a( *this ); a /= rhs; return a; }
75 
76  private:
77  T operator()() const { return comma::math::cyclic< T >::operator()(); }
78 };
79 
80 inline radians::radians( degrees d ) { value = d.value * static_cast< double >( M_PI ) / 180; }
81 
82 inline degrees::degrees( radians d ) { value = d.value * 180 / static_cast< double >( M_PI ); }
83 
84 } } // namespace snark{ namespace math{
85 
86 #endif // SNARK_MATH_ANGLE_H_