Browse Source

Faster alternatives for rotation around main axes.

pull/279/head
Vladimír Vondruš 14 years ago
parent
commit
ecad221a8b
  1. 62
      src/Math/Matrix4.h
  2. 30
      src/Math/Test/Matrix4Test.cpp
  3. 3
      src/Math/Test/Matrix4Test.h

62
src/Math/Matrix4.h

@ -73,6 +73,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param angle Rotation angle (counterclockwise, in radians)
* @param vec Normalized rotation axis
*
* If possible, use faster alternatives like xRotation(), yRotation()
* or zRotation().
* @see rotation() const, Matrix3::rotation(T), Vector3::xAxis(),
* Vector3::yAxis(), Vector3::zAxis(), deg(), rad()
* @attention Assertion fails on non-normalized rotation vector and
@ -110,6 +112,66 @@ template<class T> class Matrix4: public Matrix<4, T> {
);
}
/**
* @brief 3D rotation around X axis
* @param angle Rotation angle (counterclockwise, in radians)
*
* Faster than calling `Matrix4::rotation(angle, Vector3::xAxis())`.
* @see rotation(T, const Vector3&), yRotation(), zRotation(),
* rotation() const, Matrix3::rotation(T), deg(), rad()
*/
static Matrix4<T> xRotation(T angle) {
T sine = std::sin(angle);
T cosine = std::cos(angle);
return Matrix4<T>( /* Column-major! */
T(1), T(0), T(0), T(0),
T(0), cosine, sine, T(0),
T(0), -sine, cosine, T(0),
T(0), T(0), T(0), T(1)
);
}
/**
* @brief 3D rotation around Y axis
* @param angle Rotation angle (counterclockwise, in radians)
*
* Faster than calling `Matrix4::rotation(angle, Vector3::yAxis())`.
* @see rotation(T, const Vector3&), xRotation(), zRotation(),
* rotation() const, Matrix3::rotation(T), deg(), rad()
*/
static Matrix4<T> yRotation(T angle) {
T sine = std::sin(angle);
T cosine = std::cos(angle);
return Matrix4<T>( /* Column-major! */
cosine, T(0), -sine, T(0),
T(0), T(1), T(0), T(0),
sine, T(0), cosine, T(0),
T(0), T(0), T(0), T(1)
);
}
/**
* @brief 3D rotation matrix around Z axis
* @param angle Rotation angle (counterclockwise, in radians)
*
* Faster than calling `Matrix4::rotation(angle, Vector3::zAxis())`.
* @see rotation(T, const Vector3&), xRotation(), yRotation(),
* rotation() const, Matrix3::rotation(T), deg(), rad()
*/
static Matrix4<T> zRotation(T angle) {
T sine = std::sin(angle);
T cosine = std::cos(angle);
return Matrix4<T>( /* Column-major! */
cosine, sine, T(0), T(0),
-sine, cosine, T(0), T(0),
T(0), T(0), T(1), T(0),
T(0), T(0), T(0), T(1)
);
}
/** @copydoc Matrix::Matrix(ZeroType) */
inline constexpr explicit Matrix4(typename Matrix<4, T>::ZeroType): Matrix<4, T>(Matrix<4, T>::Zero) {}

30
src/Math/Test/Matrix4Test.cpp

@ -36,6 +36,9 @@ Matrix4Test::Matrix4Test() {
&Matrix4Test::translation,
&Matrix4Test::scaling,
&Matrix4Test::rotation,
&Matrix4Test::xRotation,
&Matrix4Test::yRotation,
&Matrix4Test::zRotation,
&Matrix4Test::rotationScalingPart,
&Matrix4Test::rotationPart,
&Matrix4Test::translationPart,
@ -105,6 +108,33 @@ void Matrix4Test::rotation() {
CORRADE_COMPARE(Matrix4::rotation(deg(-74.0f), Vector3(-1.0f, 2.0f, 2.0f).normalized()), matrix);
}
void Matrix4Test::xRotation() {
Matrix4 matrix(1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.90096887f, 0.43388374f, 0.0f,
0.0f, -0.43388374f, 0.90096887f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
CORRADE_COMPARE(Matrix4::rotation(rad(Math::Constants<float>::pi()/7), Vector3::xAxis()), matrix);
CORRADE_COMPARE(Matrix4::xRotation(rad(Math::Constants<float>::pi()/7)), matrix);
}
void Matrix4Test::yRotation() {
Matrix4 matrix(0.90096887f, 0.0f, -0.43388374f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.43388374f, 0.0f, 0.90096887f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
CORRADE_COMPARE(Matrix4::rotation(rad(Math::Constants<float>::pi()/7), Vector3::yAxis()), matrix);
CORRADE_COMPARE(Matrix4::yRotation(rad(Math::Constants<float>::pi()/7)), matrix);
}
void Matrix4Test::zRotation() {
Matrix4 matrix( 0.90096887f, 0.43388374f, 0.0f, 0.0f,
-0.43388374f, 0.90096887f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
CORRADE_COMPARE(Matrix4::rotation(rad(Math::Constants<float>::pi()/7), Vector3::zAxis()), matrix);
CORRADE_COMPARE(Matrix4::zRotation(rad(Math::Constants<float>::pi()/7)), matrix);
}
void Matrix4Test::rotationScalingPart() {
Matrix4 m(
3.0f, 5.0f, 8.0f, 4.0f,

3
src/Math/Test/Matrix4Test.h

@ -28,6 +28,9 @@ class Matrix4Test: public Corrade::TestSuite::Tester<Matrix4Test> {
void translation();
void scaling();
void rotation();
void xRotation();
void yRotation();
void zRotation();
void rotationScalingPart();
void rotationPart();
void translationPart();

Loading…
Cancel
Save