EulerAngles.h
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 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_EULERANGLES_H
11 #define EIGEN_EULERANGLES_H
12 
13 namespace Eigen {
14 
31 template<typename Derived>
32 inline Matrix<typename MatrixBase<Derived>::Scalar,3,1>
34 {
35  /* Implemented from Graphics Gems IV */
36  EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,3)
37 
40  const Scalar epsilon = NumTraits<Scalar>::dummy_precision();
41 
42  const Index odd = ((a0+1)%3 == a1) ? 0 : 1;
43  const Index i = a0;
44  const Index j = (a0 + 1 + odd)%3;
45  const Index k = (a0 + 2 - odd)%3;
46 
47  if (a0==a2)
48  {
49  Scalar s = Vector2(coeff(j,i) , coeff(k,i)).norm();
50  res[1] = internal::atan2(s, coeff(i,i));
51  if (s > epsilon)
52  {
53  res[0] = internal::atan2(coeff(j,i), coeff(k,i));
54  res[2] = internal::atan2(coeff(i,j),-coeff(i,k));
55  }
56  else
57  {
58  res[0] = Scalar(0);
59  res[2] = (coeff(i,i)>0?1:-1)*internal::atan2(-coeff(k,j), coeff(j,j));
60  }
61  }
62  else
63  {
64  Scalar c = Vector2(coeff(i,i) , coeff(i,j)).norm();
65  res[1] = internal::atan2(-coeff(i,k), c);
66  if (c > epsilon)
67  {
68  res[0] = internal::atan2(coeff(j,k), coeff(k,k));
69  res[2] = internal::atan2(coeff(i,j), coeff(i,i));
70  }
71  else
72  {
73  res[0] = Scalar(0);
74  res[2] = (coeff(i,k)>0?1:-1)*internal::atan2(-coeff(k,j), coeff(j,j));
75  }
76  }
77  if (!odd)
78  res = -res;
79  return res;
80 }
81 
82 } // end namespace Eigen
83 
84 #endif // EIGEN_EULERANGLES_H