Sat, 28 Jan 2017 17:14:05 +0200
Reworked the Matrix interface so that less index math is involved
src/basics.cpp | file | annotate | diff | comparison | revisions | |
src/editmodes/circleMode.cpp | file | annotate | diff | comparison | revisions | |
src/ldDocument.cpp | file | annotate | diff | comparison | revisions | |
src/ldObject.cpp | file | annotate | diff | comparison | revisions | |
src/mainwindow.cpp | file | annotate | diff | comparison | revisions | |
src/miscallenous.cpp | file | annotate | diff | comparison | revisions | |
src/types/matrix.cpp | file | annotate | diff | comparison | revisions | |
src/types/matrix.h | file | annotate | diff | comparison | revisions |
--- a/src/basics.cpp Sat Jan 28 16:30:27 2017 +0200 +++ b/src/basics.cpp Sat Jan 28 17:14:05 2017 +0200 @@ -37,11 +37,11 @@ QVector3D(xpos, ypos, zpos) {} -void Vertex::transform (const Matrix& matr, const Vertex& pos) +void Vertex::transform (const Matrix& matrix, const Vertex& pos) { - double x2 = (matr[0] * x()) + (matr[1] * y()) + (matr[2] * z()) + pos.x(); - double y2 = (matr[3] * x()) + (matr[4] * y()) + (matr[5] * z()) + pos.y(); - double z2 = (matr[6] * x()) + (matr[7] * y()) + (matr[8] * z()) + pos.z(); + double x2 = (matrix(0, 0) * x()) + (matrix(0, 1) * y()) + (matrix(0, 2) * z()) + pos.x(); + double y2 = (matrix(1, 0) * x()) + (matrix(1, 1) * y()) + (matrix(1, 2) * z()) + pos.y(); + double z2 = (matrix(2, 0) * x()) + (matrix(2, 1) * y()) + (matrix(2, 2) * z()) + pos.z(); setX (x2); setY (y2); setZ (z2);
--- a/src/editmodes/circleMode.cpp Sat Jan 28 16:30:27 2017 +0200 +++ b/src/editmodes/circleMode.cpp Sat Jan 28 17:14:05 2017 +0200 @@ -72,12 +72,12 @@ Matrix transform = templates[renderer()->camera() % 3]; - for (int i = 0; i < 9; ++i) + for (double& value : transform) { - if (transform[i] == 2) - transform[i] = scale; - else if (transform[i] == 1 and renderer()->camera() >= 3) - transform[i] = -1; + if (value == 2) + value = scale; + else if (value == 1 and renderer()->camera() >= 3) + value = -1; } return transform;
--- a/src/ldDocument.cpp Sat Jan 28 16:30:27 2017 +0200 +++ b/src/ldDocument.cpp Sat Jan 28 17:14:05 2017 +0200 @@ -494,7 +494,7 @@ Matrix transform; for (int i = 0; i < 9; ++i) - transform[i] = tokens[i + 5].toDouble(); // 5 - 13 + transform.value(i) = tokens[i + 5].toDouble(); // 5 - 13 obj->setTransformationMatrix (transform); obj->setFileInfo (document);
--- a/src/ldObject.cpp Sat Jan 28 16:30:27 2017 +0200 +++ b/src/ldObject.cpp Sat Jan 28 17:14:05 2017 +0200 @@ -702,13 +702,13 @@ Matrix matrixModifier = IdentityMatrix; if (axisSet & (1 << X)) - matrixModifier[0] = -1; + matrixModifier(0, 0) = -1; if (axisSet & (1 << Y)) - matrixModifier[4] = -1; + matrixModifier(1, 1) = -1; if (axisSet & (1 << Z)) - matrixModifier[8] = -1; + matrixModifier(2, 2) = -1; setTransformationMatrix (transformationMatrix() * matrixModifier); return;
--- a/src/mainwindow.cpp Sat Jan 28 16:30:27 2017 +0200 +++ b/src/mainwindow.cpp Sat Jan 28 17:14:05 2017 +0200 @@ -435,7 +435,7 @@ descr = format ("%1 %2, (", ref->fileInfo()->getDisplayName(), ref->position().toString (true)); for (int i = 0; i < 9; ++i) - descr += format ("%1%2", ref->transformationMatrix()[i], (i != 8) ? " " : ""); + descr += format ("%1%2", ref->transformationMatrix().value(i), (i != 8) ? " " : ""); descr += ')'; break;
--- a/src/miscallenous.cpp Sat Jan 28 16:30:27 2017 +0200 +++ b/src/miscallenous.cpp Sat Jan 28 17:14:05 2017 +0200 @@ -75,13 +75,13 @@ void applyToMatrix (Matrix& a, ApplyToMatrixFunction func) { for (int i = 0; i < 9; ++i) - func (i, a[i]); + func(i, a.value(i)); } void applyToMatrix (const Matrix& a, ApplyToMatrixConstFunction func) { for (int i = 0; i < 9; ++i) - func (i, a[i]); + func(i, a.value(i)); }
--- a/src/types/matrix.cpp Sat Jan 28 16:30:27 2017 +0200 +++ b/src/types/matrix.cpp Sat Jan 28 17:14:05 2017 +0200 @@ -20,15 +20,13 @@ #include "../format.h" #include "matrix.h" -/** - * @brief Matrix::Matrix - * Default-constructor for a matrix -- does not actually initialize the member values. +/* + * Default-constructor for a matrix */ -Matrix::Matrix() {} +Matrix::Matrix() : + m_values{0} {} -/** - * @brief Matrix::Matrix - * @param values +/* * Initializes the matrix from a C array * Note: the array must have (at least) 9 values! */ @@ -38,20 +36,13 @@ m_values[i] = values[i]; } -/** - * @brief Matrix::Matrix - * @param fillvalue +/* * Constructs a matrix from a single fill value. */ -Matrix::Matrix (double fillvalue) -{ - for (int i = 0; i < 9; ++i) - m_values[i] = fillvalue; -} +Matrix::Matrix (double fillvalue) : + m_values {fillvalue} {} -/** - * @brief Matrix::Matrix - * @param values +/* * Constructs a matrix from an initializer list. * Note: the initializer list must have exactly 9 values. */ @@ -61,8 +52,7 @@ memcpy (&m_values[0], values.begin(), sizeof m_values); } -/** - * @brief Matrix::dump +/* * Prints the matrix out. */ void Matrix::dump() const @@ -76,9 +66,8 @@ } } -/** - * @brief Matrix::toString - * @return a string representation of the matrix +/* + * Returns a string representation of the matrix */ QString Matrix::toString() const { @@ -95,8 +84,7 @@ return val; } -/** - * @brief Matrix::zero +/* * Fills the matrix with zeros */ void Matrix::zero() @@ -104,28 +92,24 @@ memset (&m_values[0], 0, sizeof m_values); } -/** - * @brief Matrix::multiply - * @param other - * @return this matrix multiplied with @c other. - * @note @c a.mult(b) is not equivalent to @c b.mult(a) +/* + * Performs matrix multiplication. + * Note: A*B is not equivalent to B*A! */ Matrix Matrix::multiply (const Matrix& other) const { Matrix result; - result.zero(); for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) for (int k = 0; k < 3; ++k) - result[(i * 3) + j] += m_values[(i * 3) + k] * other[(k * 3) + j]; + result[i][j] += (*this)[i][k] * other[k][j]; return result; } -/** - * @brief Matrix::determinant - * @return the matrix's determinant +/* + * Returns the matrix's determinant */ double Matrix::determinant() const { @@ -137,10 +121,48 @@ (value (0) * value (5) * value (7)); } -/** - * @brief Matrix::operator == - * @param other - * @return whether the two matrices are equal +/* + * Returns a value in matrix value (index math must be done manually) + */ +double& Matrix::value(int index) +{ + return m_values[index]; +} + +/* + * Returns a value in matrix value (index math must be done manually) + */ +const double& Matrix::value(int index) const +{ + return m_values[index]; +} + +/* + * Performs matrix multiplication + */ +Matrix Matrix::operator*(const Matrix &other) const +{ + return multiply(other); +} + +/* + * Returns a row of the matrix + */ +Matrix::RowView Matrix::operator[](int row) +{ + return RowView {*this, row}; +} + +/* + * Returns a row of the matrix + */ +Matrix::ConstRowView Matrix::operator[](int row) const +{ + return ConstRowView {*this, row}; +} + +/* + * Checks whether the two matrices are equal */ bool Matrix::operator==(const Matrix& other) const { @@ -162,3 +184,70 @@ return not operator==(other); } +double& Matrix::operator()(int row, int column) +{ + return m_values[row * 3 + column]; +} + +const double& Matrix::operator()(int row, int column) const +{ + return m_values[row * 3 + column]; +} + +double* Matrix::begin() +{ + return m_values; +} + +const double* Matrix::begin() const +{ + return m_values; +} + +double* Matrix::end() +{ + return m_values + countof(m_values); +} + +const double* Matrix::end() const +{ + return m_values + countof(m_values); +} + +Matrix::RowView::RowView(Matrix &matrix, int row) : + _matrix {matrix}, + _row {row} {} + +double& Matrix::RowView::operator[](int column) +{ + return _matrix.value(_row * 3 + column); +} + +Matrix& Matrix::RowView::matrix() const +{ + return _matrix; +} + +int Matrix::RowView::row() +{ + return _row; +} + +Matrix::ConstRowView::ConstRowView(const Matrix &matrix, int row) : + _matrix {matrix}, + _row {row} {} + +const double& Matrix::ConstRowView::operator[](int column) +{ + return _matrix.value(_row * 3 + column); +} + +const Matrix& Matrix::ConstRowView::matrix() const +{ + return _matrix; +} + +int Matrix::ConstRowView::row() +{ + return _row; +} \ No newline at end of file
--- a/src/types/matrix.h Sat Jan 28 16:30:27 2017 +0200 +++ b/src/types/matrix.h Sat Jan 28 17:14:05 2017 +0200 @@ -19,41 +19,73 @@ #pragma once #include <QString> -/** - * @brief The Matrix class +/* * A mathematical 3 x 3 matrix */ class Matrix { public: + class RowView; + class ConstRowView; + Matrix(); Matrix (const std::initializer_list<double>& values); Matrix (double fillval); Matrix (double values[]); + double* begin(); + const double* begin() const; double determinant() const; - Matrix multiply (const Matrix& other) const; void dump() const; + double* end(); + const double* end() const; + Matrix multiply(const Matrix& other) const; QString toString() const; + double& value(int index); + const double& value(int index) const; void zero(); + bool operator==(const Matrix& other) const; bool operator!=(const Matrix& other) const; - - /// @returns a mutable reference to a value by @c idx. - inline double& value (int idx) { return m_values[idx]; } - - /// @returns a const reference to a value by @c idx. - inline const double& value (int idx) const { return m_values[idx]; } - - /// @returns this matrix multiplied by @c other. - inline Matrix operator* (const Matrix& other) const { return multiply (other); } - - /// @returns a mutable reference to a value by @c idx. - inline double& operator[] (int idx) { return value(idx); } - - /// @returns a const reference to a value by @c idx. - inline const double& operator[] (int idx) const { return value (idx); } + Matrix operator*(const Matrix& other) const; + RowView operator[](int row); + ConstRowView operator[](int row) const; + double& operator()(int row, int column); + const double& operator()(int row, int column) const; private: double m_values[9]; }; + +/* + * A structure that provides a view into a row in a matrix. + * This is returned by operator[] so that the matrix can be accessed by A[i][j] + */ +class Matrix::RowView +{ +public: + RowView(Matrix &matrix, int row); + double& operator[](int column); + Matrix& matrix() const; + int row(); + +private: + Matrix& _matrix; + const int _row; +}; + +/* + * Const version of the above + */ +class Matrix::ConstRowView +{ +public: + ConstRowView(const Matrix &matrix, int row); + const double& operator[](int column); + const Matrix& matrix() const; + int row(); + +private: + const Matrix& _matrix; + const int _row; +};