diff --git a/doc/matrix-vector.dox b/doc/matrix-vector.dox index ea2421c60..82ab2d98b 100644 --- a/doc/matrix-vector.dox +++ b/doc/matrix-vector.dox @@ -129,6 +129,12 @@ Vector<3, Int> b; b[1] = 1; // second element @endcode +Row vectors can be accessed too, but only for reading, and the access is slower +due to the way the matrix is stored (see explanation below): +@code +Vector<2, Int> c = a.row(2); // third row +@endcode + Fixed-size vector subclasses have functions for accessing named components and subparts: @code diff --git a/src/Math/Matrix.h b/src/Math/Matrix.h index ae01c1c22..1fe7c40d0 100644 --- a/src/Math/Matrix.h +++ b/src/Math/Matrix.h @@ -199,6 +199,9 @@ template inline Corrade::Utility::Debug operator<<(Co } \ inline constexpr const VectorType operator[](std::size_t col) const { \ return VectorType(Matrix::operator[](col)); \ + } \ + inline VectorType row(std::size_t row) const { \ + return VectorType(Matrix::row(row)); \ } \ \ inline Type operator*(const Matrix& other) const { \ diff --git a/src/Math/RectangularMatrix.h b/src/Math/RectangularMatrix.h index 5e867c9cb..fb869992d 100644 --- a/src/Math/RectangularMatrix.h +++ b/src/Math/RectangularMatrix.h @@ -154,7 +154,7 @@ template class RectangularMatrix { * Float a = m[2][1]; * @endcode * - * @see data() + * @see row(), data() */ inline Vector& operator[](std::size_t col) { return _data[col]; @@ -164,6 +164,22 @@ template class RectangularMatrix { return _data[col]; } + /** + * @brief %Matrix row + * + * Consider using transposed() when accessing rows frequently, as this + * is slower than accessing columns due to the way the matrix is stored. + * @see operator[]() + */ + inline Vector row(std::size_t row) const { + Vector out; + + for(std::size_t i = 0; i != cols; ++i) + out[i] = _data[i][row]; + + return out; + } + /** @brief Equality comparison */ inline bool operator==(const RectangularMatrix& other) const { for(std::size_t i = 0; i != cols; ++i) @@ -336,7 +352,11 @@ template class RectangularMatrix { return operator*(RectangularMatrix<1, rows, T>(other))[0]; } - /** @brief Transposed matrix */ + /** + * @brief Transposed matrix + * + * @see row() + */ RectangularMatrix transposed() const { RectangularMatrix out; diff --git a/src/Math/Test/RectangularMatrixTest.cpp b/src/Math/Test/RectangularMatrixTest.cpp index 05af6ccc8..7c2c22289 100644 --- a/src/Math/Test/RectangularMatrixTest.cpp +++ b/src/Math/Test/RectangularMatrixTest.cpp @@ -40,7 +40,9 @@ class RectangularMatrixTest: public Corrade::TestSuite::Tester { void constructFromData(); void constructFromDiagonal(); void constructCopy(); + void data(); + void row(); void compare(); @@ -79,7 +81,9 @@ RectangularMatrixTest::RectangularMatrixTest() { &RectangularMatrixTest::constructFromData, &RectangularMatrixTest::constructFromDiagonal, &RectangularMatrixTest::constructCopy, + &RectangularMatrixTest::data, + &RectangularMatrixTest::row, &RectangularMatrixTest::compare, @@ -199,6 +203,14 @@ void RectangularMatrixTest::data() { CORRADE_COMPARE(d, 3.0f); } +void RectangularMatrixTest::row() { + const Matrix3x4 a(Vector4(1.0f, 2.0f, 3.0f, 4.0f), + Vector4(5.0f, 6.0f, 7.0f, 8.0f), + Vector4(9.0f, 10.0f, 11.0f, 12.0f)); + + CORRADE_COMPARE(a.row(1), Vector3(2.0f, 6.0f, 10.0f)); +} + void RectangularMatrixTest::compare() { Matrix2 a(Vector2(1.0f, -3.0f), Vector2(5.0f, -10.0f));