matrix: add to_euler function
This commit is contained in:
parent
b9fbcd6866
commit
0e88b4b324
31
matrix.cpp
31
matrix.cpp
@ -391,6 +391,37 @@ template struct util::matrix<4,float>;
|
|||||||
template struct util::matrix<4,double>;
|
template struct util::matrix<4,double>;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Uses the algorithm from:
|
||||||
|
// "Extracting Euler Angles from a Rotation Matrix" by
|
||||||
|
// Mike Day, Insomniac Games.
|
||||||
|
template <size_t S, typename T>
|
||||||
|
util::vector<3,T>
|
||||||
|
util::to_euler (const matrix<S,T> &m)
|
||||||
|
{
|
||||||
|
static_assert (S == 3 || S == 4, "only defined for 3d affine transforms");
|
||||||
|
|
||||||
|
const auto theta0 = std::atan2 (m[2][1], m[2][2]);
|
||||||
|
|
||||||
|
const auto c1 = std::hypot (m[0][0], m[1][0]);
|
||||||
|
const auto theta1 = std::atan2 (-m[2][0], c1);
|
||||||
|
|
||||||
|
const auto s0 = std::sin(theta0);
|
||||||
|
const auto c0 = std::cos(theta0);
|
||||||
|
const auto theta2 = std::atan2(
|
||||||
|
s0 * m[0][2] - c0 * m[0][1],
|
||||||
|
c0 * m[1][1] - s0 * m[1][2]
|
||||||
|
);
|
||||||
|
|
||||||
|
return { theta0, theta1, theta2 };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template util::vector<3,float> util::to_euler (const matrix<3,float>&);
|
||||||
|
template util::vector<3,float> util::to_euler (const matrix<4,float>&);
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template <size_t S, typename T>
|
template <size_t S, typename T>
|
||||||
std::ostream&
|
std::ostream&
|
||||||
|
14
matrix.hpp
14
matrix.hpp
@ -83,6 +83,16 @@ namespace util {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Convert an affine rotation matrix to euler angles.
|
||||||
|
//
|
||||||
|
// Results are undefined if the matrix is not purely a rotation matrix,
|
||||||
|
// or if the dimension is not 3x3 or 4x4.
|
||||||
|
template <size_t S, typename T>
|
||||||
|
vector<3,T>
|
||||||
|
to_euler (const matrix<S,T>&);
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// logical operations
|
// logical operations
|
||||||
template <size_t S, typename T>
|
template <size_t S, typename T>
|
||||||
@ -152,6 +162,8 @@ namespace util {
|
|||||||
T
|
T
|
||||||
sum (const matrix<S,T>&);
|
sum (const matrix<S,T>&);
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
template <typename T> using matrix3 = matrix<3,T>;
|
template <typename T> using matrix3 = matrix<3,T>;
|
||||||
template <typename T> using matrix4 = matrix<4,T>;
|
template <typename T> using matrix4 = matrix<4,T>;
|
||||||
|
|
||||||
@ -167,6 +179,8 @@ namespace util {
|
|||||||
typedef matrix<4,float> matrix4f;
|
typedef matrix<4,float> matrix4f;
|
||||||
typedef matrix<4,double> matrix4d;
|
typedef matrix<4,double> matrix4d;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
template <size_t S, typename T>
|
template <size_t S, typename T>
|
||||||
std::ostream& operator<< (std::ostream&, const matrix<S,T>&);
|
std::ostream& operator<< (std::ostream&, const matrix<S,T>&);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user