~choreonoid/choreonoid/debian

« back to all changes in this revision

Viewing changes to thirdparty/eigen3/Eigen/src/Geometry/AngleAxis.h

  • Committer: Thomas Moulard
  • Date: 2012-10-23 12:43:24 UTC
  • Revision ID: git-v1:351cf736ad49bc7a9a7b9767dee760a013517a5d
Tags: upstream/1.1.0
ImportedĀ UpstreamĀ versionĀ 1.1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// This file is part of Eigen, a lightweight C++ template library
 
2
// for linear algebra.
 
3
//
 
4
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
 
5
//
 
6
// Eigen 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
// Alternatively, you can redistribute it and/or
 
12
// modify it under the terms of the GNU General Public License as
 
13
// published by the Free Software Foundation; either version 2 of
 
14
// the License, or (at your option) any later version.
 
15
//
 
16
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
 
17
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
18
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
 
19
// GNU General Public License for more details.
 
20
//
 
21
// You should have received a copy of the GNU Lesser General Public
 
22
// License and a copy of the GNU General Public License along with
 
23
// Eigen. If not, see <http://www.gnu.org/licenses/>.
 
24
 
 
25
#ifndef EIGEN_ANGLEAXIS_H
 
26
#define EIGEN_ANGLEAXIS_H
 
27
 
 
28
/** \geometry_module \ingroup Geometry_Module
 
29
  *
 
30
  * \class AngleAxis
 
31
  *
 
32
  * \brief Represents a 3D rotation as a rotation angle around an arbitrary 3D axis
 
33
  *
 
34
  * \param _Scalar the scalar type, i.e., the type of the coefficients.
 
35
  *
 
36
  * \warning When setting up an AngleAxis object, the axis vector \b must \b be \b normalized.
 
37
  *
 
38
  * The following two typedefs are provided for convenience:
 
39
  * \li \c AngleAxisf for \c float
 
40
  * \li \c AngleAxisd for \c double
 
41
  *
 
42
  * Combined with MatrixBase::Unit{X,Y,Z}, AngleAxis can be used to easily
 
43
  * mimic Euler-angles. Here is an example:
 
44
  * \include AngleAxis_mimic_euler.cpp
 
45
  * Output: \verbinclude AngleAxis_mimic_euler.out
 
46
  *
 
47
  * \note This class is not aimed to be used to store a rotation transformation,
 
48
  * but rather to make easier the creation of other rotation (Quaternion, rotation Matrix)
 
49
  * and transformation objects.
 
50
  *
 
51
  * \sa class Quaternion, class Transform, MatrixBase::UnitX()
 
52
  */
 
53
 
 
54
namespace internal {
 
55
template<typename _Scalar> struct traits<AngleAxis<_Scalar> >
 
56
{
 
57
  typedef _Scalar Scalar;
 
58
};
 
59
}
 
60
 
 
61
template<typename _Scalar>
 
62
class AngleAxis : public RotationBase<AngleAxis<_Scalar>,3>
 
63
{
 
64
  typedef RotationBase<AngleAxis<_Scalar>,3> Base;
 
65
 
 
66
public:
 
67
 
 
68
  using Base::operator*;
 
69
 
 
70
  enum { Dim = 3 };
 
71
  /** the scalar type of the coefficients */
 
72
  typedef _Scalar Scalar;
 
73
  typedef Matrix<Scalar,3,3> Matrix3;
 
74
  typedef Matrix<Scalar,3,1> Vector3;
 
75
  typedef Quaternion<Scalar> QuaternionType;
 
76
 
 
77
protected:
 
78
 
 
79
  Vector3 m_axis;
 
80
  Scalar m_angle;
 
81
 
 
82
public:
 
83
 
 
84
  /** Default constructor without initialization. */
 
85
  AngleAxis() {}
 
86
  /** Constructs and initialize the angle-axis rotation from an \a angle in radian
 
87
    * and an \a axis which \b must \b be \b normalized.
 
88
    *
 
89
    * \warning If the \a axis vector is not normalized, then the angle-axis object
 
90
    *          represents an invalid rotation. */
 
91
  template<typename Derived>
 
92
  inline AngleAxis(Scalar angle, const MatrixBase<Derived>& axis) : m_axis(axis), m_angle(angle) {}
 
93
  /** Constructs and initialize the angle-axis rotation from a quaternion \a q. */
 
94
  template<typename QuatDerived> inline explicit AngleAxis(const QuaternionBase<QuatDerived>& q) { *this = q; }
 
95
  /** Constructs and initialize the angle-axis rotation from a 3x3 rotation matrix. */
 
96
  template<typename Derived>
 
97
  inline explicit AngleAxis(const MatrixBase<Derived>& m) { *this = m; }
 
98
 
 
99
  Scalar angle() const { return m_angle; }
 
100
  Scalar& angle() { return m_angle; }
 
101
 
 
102
  const Vector3& axis() const { return m_axis; }
 
103
  Vector3& axis() { return m_axis; }
 
104
 
 
105
  /** Concatenates two rotations */
 
106
  inline QuaternionType operator* (const AngleAxis& other) const
 
107
  { return QuaternionType(*this) * QuaternionType(other); }
 
108
 
 
109
  /** Concatenates two rotations */
 
110
  inline QuaternionType operator* (const QuaternionType& other) const
 
111
  { return QuaternionType(*this) * other; }
 
112
 
 
113
  /** Concatenates two rotations */
 
114
  friend inline QuaternionType operator* (const QuaternionType& a, const AngleAxis& b)
 
115
  { return a * QuaternionType(b); }
 
116
 
 
117
  /** \returns the inverse rotation, i.e., an angle-axis with opposite rotation angle */
 
118
  AngleAxis inverse() const
 
119
  { return AngleAxis(-m_angle, m_axis); }
 
120
 
 
121
  template<class QuatDerived>
 
122
  AngleAxis& operator=(const QuaternionBase<QuatDerived>& q);
 
123
  template<typename Derived>
 
124
  AngleAxis& operator=(const MatrixBase<Derived>& m);
 
125
 
 
126
  template<typename Derived>
 
127
  AngleAxis& fromRotationMatrix(const MatrixBase<Derived>& m);
 
128
  Matrix3 toRotationMatrix(void) const;
 
129
 
 
130
  /** \returns \c *this with scalar type casted to \a NewScalarType
 
131
    *
 
132
    * Note that if \a NewScalarType is equal to the current scalar type of \c *this
 
133
    * then this function smartly returns a const reference to \c *this.
 
134
    */
 
135
  template<typename NewScalarType>
 
136
  inline typename internal::cast_return_type<AngleAxis,AngleAxis<NewScalarType> >::type cast() const
 
137
  { return typename internal::cast_return_type<AngleAxis,AngleAxis<NewScalarType> >::type(*this); }
 
138
 
 
139
  /** Copy constructor with scalar type conversion */
 
140
  template<typename OtherScalarType>
 
141
  inline explicit AngleAxis(const AngleAxis<OtherScalarType>& other)
 
142
  {
 
143
    m_axis = other.axis().template cast<Scalar>();
 
144
    m_angle = Scalar(other.angle());
 
145
  }
 
146
 
 
147
  inline static const AngleAxis Identity() { return AngleAxis(0, Vector3::UnitX()); }
 
148
 
 
149
  /** \returns \c true if \c *this is approximately equal to \a other, within the precision
 
150
    * determined by \a prec.
 
151
    *
 
152
    * \sa MatrixBase::isApprox() */
 
153
  bool isApprox(const AngleAxis& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
 
154
  { return m_axis.isApprox(other.m_axis, prec) && internal::isApprox(m_angle,other.m_angle, prec); }
 
155
};
 
156
 
 
157
/** \ingroup Geometry_Module
 
158
  * single precision angle-axis type */
 
159
typedef AngleAxis<float> AngleAxisf;
 
160
/** \ingroup Geometry_Module
 
161
  * double precision angle-axis type */
 
162
typedef AngleAxis<double> AngleAxisd;
 
163
 
 
164
/** Set \c *this from a \b unit quaternion.
 
165
  * The axis is normalized.
 
166
  * 
 
167
  * \warning As any other method dealing with quaternion, if the input quaternion
 
168
  *          is not normalized then the result is undefined.
 
169
  */
 
170
template<typename Scalar>
 
171
template<typename QuatDerived>
 
172
AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q)
 
173
{
 
174
  using std::acos;
 
175
  using std::min;
 
176
  using std::max;
 
177
  Scalar n2 = q.vec().squaredNorm();
 
178
  if (n2 < NumTraits<Scalar>::dummy_precision()*NumTraits<Scalar>::dummy_precision())
 
179
  {
 
180
    m_angle = 0;
 
181
    m_axis << 1, 0, 0;
 
182
  }
 
183
  else
 
184
  {
 
185
    m_angle = Scalar(2)*acos(min(max(Scalar(-1),q.w()),Scalar(1)));
 
186
    m_axis = q.vec() / internal::sqrt(n2);
 
187
  }
 
188
  return *this;
 
189
}
 
190
 
 
191
/** Set \c *this from a 3x3 rotation matrix \a mat.
 
192
  */
 
193
template<typename Scalar>
 
194
template<typename Derived>
 
195
AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const MatrixBase<Derived>& mat)
 
196
{
 
197
  // Since a direct conversion would not be really faster,
 
198
  // let's use the robust Quaternion implementation:
 
199
  return *this = QuaternionType(mat);
 
200
}
 
201
 
 
202
/**
 
203
* \brief Sets \c *this from a 3x3 rotation matrix.
 
204
**/
 
205
template<typename Scalar>
 
206
template<typename Derived>
 
207
AngleAxis<Scalar>& AngleAxis<Scalar>::fromRotationMatrix(const MatrixBase<Derived>& mat)
 
208
{
 
209
  return *this = QuaternionType(mat);
 
210
}
 
211
 
 
212
/** Constructs and \returns an equivalent 3x3 rotation matrix.
 
213
  */
 
214
template<typename Scalar>
 
215
typename AngleAxis<Scalar>::Matrix3
 
216
AngleAxis<Scalar>::toRotationMatrix(void) const
 
217
{
 
218
  Matrix3 res;
 
219
  Vector3 sin_axis  = internal::sin(m_angle) * m_axis;
 
220
  Scalar c = internal::cos(m_angle);
 
221
  Vector3 cos1_axis = (Scalar(1)-c) * m_axis;
 
222
 
 
223
  Scalar tmp;
 
224
  tmp = cos1_axis.x() * m_axis.y();
 
225
  res.coeffRef(0,1) = tmp - sin_axis.z();
 
226
  res.coeffRef(1,0) = tmp + sin_axis.z();
 
227
 
 
228
  tmp = cos1_axis.x() * m_axis.z();
 
229
  res.coeffRef(0,2) = tmp + sin_axis.y();
 
230
  res.coeffRef(2,0) = tmp - sin_axis.y();
 
231
 
 
232
  tmp = cos1_axis.y() * m_axis.z();
 
233
  res.coeffRef(1,2) = tmp - sin_axis.x();
 
234
  res.coeffRef(2,1) = tmp + sin_axis.x();
 
235
 
 
236
  res.diagonal() = (cos1_axis.cwiseProduct(m_axis)).array() + c;
 
237
 
 
238
  return res;
 
239
}
 
240
 
 
241
#endif // EIGEN_ANGLEAXIS_H