Browse Source

Math: ability to slice or expand square matrices.

pull/268/merge
Vladimír Vondruš 8 years ago
parent
commit
8d5454b8ff
  1. 2
      doc/changelog.dox
  2. 27
      src/Magnum/Math/Matrix.h
  3. 9
      src/Magnum/Math/Matrix3.h
  4. 9
      src/Magnum/Math/Matrix4.h
  5. 25
      src/Magnum/Math/Test/Matrix3Test.cpp
  6. 27
      src/Magnum/Math/Test/Matrix4Test.cpp
  7. 29
      src/Magnum/Math/Test/MatrixTest.cpp

2
doc/changelog.dox

@ -114,6 +114,8 @@ See also:
@ref Math::Distance::pointPlane() and others
- Ability to convert @ref Math::BoolVector from and to external
representation
- Ability to construct @ref Math::Matrix from a smaller or larger square
matrix by slicing or expanding it
- Mutable overloads for @ref Math::Complex::real(),
@ref Math::Complex::imaginary(), @ref Math::Dual::real(),
@ref Math::Dual::dual(), @ref Math::Quaternion::vector() and

27
src/Magnum/Math/Matrix.h

@ -35,6 +35,15 @@ namespace Magnum { namespace Math {
namespace Implementation {
template<std::size_t, class> struct MatrixDeterminant;
template<std::size_t size, std::size_t col, std::size_t otherSize, class T, std::size_t ...row> constexpr Vector<size, T> valueOrIdentityVector(Sequence<row...>, const RectangularMatrix<otherSize, otherSize, T>& other) {
return {(col < otherSize && row < otherSize ? other[col][row] :
col == row ? T{1} : T{0})...};
}
template<std::size_t size, std::size_t col, std::size_t otherSize, class T> constexpr Vector<size, T> valueOrIdentityVector(const RectangularMatrix<otherSize, otherSize, T>& other) {
return valueOrIdentityVector<size, col>(typename Implementation::GenerateSequence<size>::Type(), other);
}
}
/**
@ -111,6 +120,20 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
/** @brief Construct matrix from external representation */
template<class U, class V = decltype(Implementation::RectangularMatrixConverter<size, size, T, U>::from(std::declval<U>()))> constexpr explicit Matrix(const U& other): RectangularMatrix<size, size, T>(Implementation::RectangularMatrixConverter<size, size, T, U>::from(other)) {}
/**
* @brief Construct matrix by slicing or expanding another of a different size
*
* If the other matrix is larger, takes only the first @cpp size @ce
* columns and rows from it; if the other matrix is smaller, it's
* expanded to an identity (ones on diagonal, zeros elsewhere).
*/
template<std::size_t otherSize> constexpr explicit Matrix(const RectangularMatrix<otherSize, otherSize, T>& other) noexcept
/** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT
: Matrix<size, T>{typename Implementation::GenerateSequence<size>::Type(), other}
#endif
{}
/** @brief Copy constructor */
constexpr /*implicit*/ Matrix(const RectangularMatrix<size, size, T>& other) noexcept: RectangularMatrix<size, size, T>(other) {}
@ -199,6 +222,10 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
}
MAGNUM_RECTANGULARMATRIX_SUBCLASS_IMPLEMENTATION(size, size, Matrix<size, T>)
#endif
private:
/* Implementation for RectangularMatrix<cols, rows, T>::RectangularMatrix(const RectangularMatrix<cols, rows, U>&) */
template<std::size_t otherSize, std::size_t ...col> constexpr explicit Matrix(Implementation::Sequence<col...>, const RectangularMatrix<otherSize, otherSize, T>& other) noexcept: RectangularMatrix<size, size, T>{Implementation::valueOrIdentityVector<size, col>(other)...} {}
};
/**

9
src/Magnum/Math/Matrix3.h

@ -241,6 +241,15 @@ template<class T> class Matrix3: public Matrix3x3<T> {
/** @brief Construct matrix from external representation */
template<class U, class V = decltype(Implementation::RectangularMatrixConverter<3, 3, T, U>::from(std::declval<U>()))> constexpr explicit Matrix3(const U& other) noexcept: Matrix3x3<T>(Implementation::RectangularMatrixConverter<3, 3, T, U>::from(other)) {}
/**
* @brief Construct matrix by slicing or expanding another of a different size
*
* If the other matrix is larger, takes only the first @cpp size @ce
* columns and rows from it; if the other matrix is smaller, it's
* expanded to an identity (ones on diagonal, zeros elsewhere).
*/
template<std::size_t otherSize> constexpr explicit Matrix3(const RectangularMatrix<otherSize, otherSize, T>& other) noexcept: Matrix3x3<T>{other} {}
/** @brief Copy constructor */
constexpr /*implicit*/ Matrix3(const RectangularMatrix<3, 3, T>& other) noexcept: Matrix3x3<T>(other) {}

9
src/Magnum/Math/Matrix4.h

@ -426,6 +426,15 @@ template<class T> class Matrix4: public Matrix4x4<T> {
/** @brief Construct matrix from external representation */
template<class U, class V = decltype(Implementation::RectangularMatrixConverter<4, 4, T, U>::from(std::declval<U>()))> constexpr explicit Matrix4(const U& other): Matrix4x4<T>(Implementation::RectangularMatrixConverter<4, 4, T, U>::from(other)) {}
/**
* @brief Construct matrix by slicing or expanding another of a different size
*
* If the other matrix is larger, takes only the first @cpp size @ce
* columns and rows from it; if the other matrix is smaller, it's
* expanded to an identity (ones on diagonal, zeros elsewhere).
*/
template<std::size_t otherSize> constexpr explicit Matrix4(const RectangularMatrix<otherSize, otherSize, T>& other) noexcept: Matrix4x4<T>{other} {}
/** @brief Copy constructor */
constexpr /*implicit*/ Matrix4(const RectangularMatrix<4, 4, T>& other) noexcept: Matrix4x4<T>(other) {}

25
src/Magnum/Math/Test/Matrix3Test.cpp

@ -65,6 +65,7 @@ struct Matrix3Test: Corrade::TestSuite::Tester {
void constructNoInit();
void constructOneValue();
void constructConversion();
void constructFromDifferentSize();
void constructCopy();
void convert();
@ -98,11 +99,11 @@ struct Matrix3Test: Corrade::TestSuite::Tester {
};
typedef Math::Deg<Float> Deg;
typedef Math::Matrix2x2<Float> Matrix2x2;
typedef Math::Matrix3<Float> Matrix3;
typedef Math::Matrix3<Int> Matrix3i;
typedef Math::Matrix2x2<Float> Matrix2x2;
typedef Math::Vector3<Float> Vector3;
typedef Math::Vector2<Float> Vector2;
typedef Math::Vector3<Float> Vector3;
Matrix3Test::Matrix3Test() {
addTests({&Matrix3Test::construct,
@ -111,6 +112,7 @@ Matrix3Test::Matrix3Test() {
&Matrix3Test::constructNoInit,
&Matrix3Test::constructOneValue,
&Matrix3Test::constructConversion,
&Matrix3Test::constructFromDifferentSize,
&Matrix3Test::constructCopy,
&Matrix3Test::convert,
@ -233,6 +235,25 @@ void Matrix3Test::constructConversion() {
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix3, Matrix3i>::value));
}
void Matrix3Test::constructFromDifferentSize() {
constexpr Matrix3 a{{3.0f, 5.0f, 8.0f},
{4.5f, 4.0f, 7.0f},
{1.0f, 2.0f, 3.0f}};
constexpr Matrix2x2 b{Vector2{3.0f, 5.0f},
Vector2{4.5f, 4.0f}};
constexpr Matrix3 c{{3.0f, 5.0f, 0.0f},
{4.5f, 4.0f, 0.0f},
{0.0f, 0.0f, 1.0f}};
constexpr Matrix3 larger{b};
CORRADE_COMPARE(larger, c);
CORRADE_COMPARE(Matrix3{b}, c);
constexpr Matrix2x2 smaller{a};
CORRADE_COMPARE(smaller, b);
CORRADE_COMPARE(Matrix2x2{a}, b);
}
void Matrix3Test::constructCopy() {
constexpr RectangularMatrix<3, 3, Float> a(Vector<3, Float>(3.0f, 5.0f, 8.0f),
Vector<3, Float>(4.5f, 4.0f, 7.0f),

27
src/Magnum/Math/Test/Matrix4Test.cpp

@ -68,6 +68,7 @@ struct Matrix4Test: Corrade::TestSuite::Tester {
void constructNoInit();
void constructOneValue();
void constructConversion();
void constructFromDifferentSize();
void constructCopy();
void convert();
@ -112,9 +113,11 @@ struct Matrix4Test: Corrade::TestSuite::Tester {
typedef Math::Deg<Float> Deg;
typedef Math::Rad<Float> Rad;
typedef Math::Matrix<2, Float> Matrix2x2;
typedef Math::Matrix<3, Float> Matrix3x3;
typedef Math::Matrix4<Float> Matrix4;
typedef Math::Matrix4<Int> Matrix4i;
typedef Math::Matrix<3, Float> Matrix3x3;
typedef Math::Vector2<Float> Vector2;
typedef Math::Vector3<Float> Vector3;
typedef Math::Vector4<Float> Vector4;
typedef Math::Constants<Float> Constants;
@ -126,6 +129,7 @@ Matrix4Test::Matrix4Test() {
&Matrix4Test::constructNoInit,
&Matrix4Test::constructOneValue,
&Matrix4Test::constructConversion,
&Matrix4Test::constructFromDifferentSize,
&Matrix4Test::constructCopy,
&Matrix4Test::convert,
@ -268,6 +272,27 @@ void Matrix4Test::constructConversion() {
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4, Matrix4i>::value));
}
void Matrix4Test::constructFromDifferentSize() {
constexpr Matrix4 a{{3.0f, 5.0f, 8.0f, -3.0f},
{4.5f, 4.0f, 7.0f, 2.0f},
{1.0f, 2.0f, 3.0f, -1.0f},
{7.9f, -1.0f, 8.0f, -1.5f}};
constexpr Matrix2x2 b{Vector2{3.0f, 5.0f},
Vector2{4.5f, 4.0f}};
constexpr Matrix4 c{{3.0f, 5.0f, 0.0f, 0.0f},
{4.5f, 4.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}};
constexpr Matrix4 larger{b};
CORRADE_COMPARE(larger, c);
CORRADE_COMPARE(Matrix4{b}, c);
constexpr Matrix2x2 smaller{a};
CORRADE_COMPARE(smaller, b);
CORRADE_COMPARE(Matrix2x2{a}, b);
}
void Matrix4Test::constructCopy() {
constexpr Matrix<4, Float> a(Vector<4, Float>(3.0f, 5.0f, 8.0f, -3.0f),
Vector<4, Float>(4.5f, 4.0f, 7.0f, 2.0f),

29
src/Magnum/Math/Test/MatrixTest.cpp

@ -66,6 +66,7 @@ struct MatrixTest: Corrade::TestSuite::Tester {
void constructOneValue();
void constructOneComponent();
void constructConversion();
void constructFromDifferentSize();
void constructCopy();
void convert();
@ -84,12 +85,14 @@ struct MatrixTest: Corrade::TestSuite::Tester {
void configuration();
};
typedef Matrix<2, Float> Matrix2x2;
typedef Matrix<3, Float> Matrix3x3;
typedef Matrix<4, Float> Matrix4x4;
typedef Matrix<4, Int> Matrix4x4i;
typedef Matrix<3, Float> Matrix3x3;
typedef Vector<2, Float> Vector2;
typedef Vector<3, Float> Vector3;
typedef Vector<4, Float> Vector4;
typedef Vector<4, Int> Vector4i;
typedef Vector<3, Float> Vector3;
typedef Math::Constants<Float> Constants;
MatrixTest::MatrixTest() {
@ -100,6 +103,7 @@ MatrixTest::MatrixTest() {
&MatrixTest::constructOneValue,
&MatrixTest::constructOneComponent,
&MatrixTest::constructConversion,
&MatrixTest::constructFromDifferentSize,
&MatrixTest::constructCopy,
&MatrixTest::convert,
@ -230,6 +234,27 @@ void MatrixTest::constructConversion() {
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4x4, Matrix4x4i>::value));
}
void MatrixTest::constructFromDifferentSize() {
constexpr Matrix4x4 a{Vector4{3.0f, 5.0f, 8.0f, -3.0f},
Vector4{4.5f, 4.0f, 7.0f, 2.0f},
Vector4{1.0f, 2.0f, 3.0f, -1.0f},
Vector4{7.9f, -1.0f, 8.0f, -1.5f}};
constexpr Matrix2x2 b{Vector2{3.0f, 5.0f},
Vector2{4.5f, 4.0f}};
constexpr Matrix4x4 c{Vector4{3.0f, 5.0f, 0.0f, 0.0f},
Vector4{4.5f, 4.0f, 0.0f, 0.0f},
Vector4{0.0f, 0.0f, 1.0f, 0.0f},
Vector4{0.0f, 0.0f, 0.0f, 1.0f}};
constexpr Matrix4x4 larger{b};
CORRADE_COMPARE(larger, c);
CORRADE_COMPARE(Matrix4x4{b}, c);
constexpr Matrix2x2 smaller{a};
CORRADE_COMPARE(smaller, b);
CORRADE_COMPARE(Matrix2x2{a}, b);
}
void MatrixTest::constructCopy() {
constexpr RectangularMatrix<4, 4, Float> a(Vector4(3.0f, 5.0f, 8.0f, -3.0f),
Vector4(4.5f, 4.0f, 7.0f, 2.0f),

Loading…
Cancel
Save