Rotation2D.h 5.11 KB
Newer Older
LM's avatar
LM committed
1 2 3 4 5
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
Don Gagne's avatar
Don Gagne committed
6 7 8
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
LM's avatar
LM committed
9 10 11 12

#ifndef EIGEN_ROTATION2D_H
#define EIGEN_ROTATION2D_H

Don Gagne's avatar
Don Gagne committed
13 14
namespace Eigen { 

LM's avatar
LM committed
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
/** \geometry_module \ingroup Geometry_Module
  *
  * \class Rotation2D
  *
  * \brief Represents a rotation/orientation in a 2 dimensional space.
  *
  * \param _Scalar the scalar type, i.e., the type of the coefficients
  *
  * This class is equivalent to a single scalar representing a counter clock wise rotation
  * as a single angle in radian. It provides some additional features such as the automatic
  * conversion from/to a 2x2 rotation matrix. Moreover this class aims to provide a similar
  * interface to Quaternion in order to facilitate the writing of generic algorithms
  * dealing with rotations.
  *
  * \sa class Quaternion, class Transform
  */

namespace internal {

template<typename _Scalar> struct traits<Rotation2D<_Scalar> >
{
  typedef _Scalar Scalar;
};
} // end namespace internal

template<typename _Scalar>
class Rotation2D : public RotationBase<Rotation2D<_Scalar>,2>
{
  typedef RotationBase<Rotation2D<_Scalar>,2> Base;

public:

  using Base::operator*;

  enum { Dim = 2 };
  /** the scalar type of the coefficients */
  typedef _Scalar Scalar;
  typedef Matrix<Scalar,2,1> Vector2;
  typedef Matrix<Scalar,2,2> Matrix2;

protected:

  Scalar m_angle;

public:

  /** Construct a 2D counter clock wise rotation from the angle \a a in radian. */
Don Gagne's avatar
Don Gagne committed
62
  inline Rotation2D(const Scalar& a) : m_angle(a) {}
63 64 65
  
  /** Default constructor wihtout initialization. The represented rotation is undefined. */
  Rotation2D() {}
LM's avatar
LM committed
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

  /** \returns the rotation angle */
  inline Scalar angle() const { return m_angle; }

  /** \returns a read-write reference to the rotation angle */
  inline Scalar& angle() { return m_angle; }

  /** \returns the inverse rotation */
  inline Rotation2D inverse() const { return -m_angle; }

  /** Concatenates two rotations */
  inline Rotation2D operator*(const Rotation2D& other) const
  { return m_angle + other.m_angle; }

  /** Concatenates two rotations */
  inline Rotation2D& operator*=(const Rotation2D& other)
Don Gagne's avatar
Don Gagne committed
82
  { m_angle += other.m_angle; return *this; }
LM's avatar
LM committed
83 84 85 86

  /** Applies the rotation to a 2D vector */
  Vector2 operator* (const Vector2& vec) const
  { return toRotationMatrix() * vec; }
87
  
LM's avatar
LM committed
88 89
  template<typename Derived>
  Rotation2D& fromRotationMatrix(const MatrixBase<Derived>& m);
90
  Matrix2 toRotationMatrix() const;
LM's avatar
LM committed
91 92 93 94

  /** \returns the spherical interpolation between \c *this and \a other using
    * parameter \a t. It is in fact equivalent to a linear interpolation.
    */
Don Gagne's avatar
Don Gagne committed
95
  inline Rotation2D slerp(const Scalar& t, const Rotation2D& other) const
LM's avatar
LM committed
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
  { return m_angle * (1-t) + other.angle() * t; }

  /** \returns \c *this with scalar type casted to \a NewScalarType
    *
    * Note that if \a NewScalarType is equal to the current scalar type of \c *this
    * then this function smartly returns a const reference to \c *this.
    */
  template<typename NewScalarType>
  inline typename internal::cast_return_type<Rotation2D,Rotation2D<NewScalarType> >::type cast() const
  { return typename internal::cast_return_type<Rotation2D,Rotation2D<NewScalarType> >::type(*this); }

  /** Copy constructor with scalar type conversion */
  template<typename OtherScalarType>
  inline explicit Rotation2D(const Rotation2D<OtherScalarType>& other)
  {
    m_angle = Scalar(other.angle());
  }

Don Gagne's avatar
Don Gagne committed
114
  static inline Rotation2D Identity() { return Rotation2D(0); }
LM's avatar
LM committed
115 116 117 118 119

  /** \returns \c true if \c *this is approximately equal to \a other, within the precision
    * determined by \a prec.
    *
    * \sa MatrixBase::isApprox() */
Don Gagne's avatar
Don Gagne committed
120
  bool isApprox(const Rotation2D& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const
LM's avatar
LM committed
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
  { return internal::isApprox(m_angle,other.m_angle, prec); }
};

/** \ingroup Geometry_Module
  * single precision 2D rotation type */
typedef Rotation2D<float> Rotation2Df;
/** \ingroup Geometry_Module
  * double precision 2D rotation type */
typedef Rotation2D<double> Rotation2Dd;

/** Set \c *this from a 2x2 rotation matrix \a mat.
  * In other words, this function extract the rotation angle
  * from the rotation matrix.
  */
template<typename Scalar>
template<typename Derived>
Rotation2D<Scalar>& Rotation2D<Scalar>::fromRotationMatrix(const MatrixBase<Derived>& mat)
{
Don Gagne's avatar
Don Gagne committed
139
  using std::atan2;
LM's avatar
LM committed
140
  EIGEN_STATIC_ASSERT(Derived::RowsAtCompileTime==2 && Derived::ColsAtCompileTime==2,YOU_MADE_A_PROGRAMMING_MISTAKE)
Don Gagne's avatar
Don Gagne committed
141
  m_angle = atan2(mat.coeff(1,0), mat.coeff(0,0));
LM's avatar
LM committed
142 143 144 145 146 147 148 149 150
  return *this;
}

/** Constructs and \returns an equivalent 2x2 rotation matrix.
  */
template<typename Scalar>
typename Rotation2D<Scalar>::Matrix2
Rotation2D<Scalar>::toRotationMatrix(void) const
{
Don Gagne's avatar
Don Gagne committed
151 152 153 154
  using std::sin;
  using std::cos;
  Scalar sinA = sin(m_angle);
  Scalar cosA = cos(m_angle);
LM's avatar
LM committed
155 156 157
  return (Matrix2() << cosA, -sinA, sinA, cosA).finished();
}

Don Gagne's avatar
Don Gagne committed
158 159
} // end namespace Eigen

LM's avatar
LM committed
160
#endif // EIGEN_ROTATION2D_H