/* * Copyright (c) 2010-2014 OTClient * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifndef MATRIX_H #define MATRIX_H #include #include #include #include template class Matrix { public: Matrix() { setIdentity(); } Matrix(int) {} // construct without initializing identity matrix Matrix(const Matrix& other) = default; template Matrix(const std::initializer_list& values) { *this = values; } template Matrix(const U *values) { *this = values; } void setIdentity(); bool isIdentity() const; void fill(T value); Matrix transposed() const; typename std::enable_if::type transpose() { *this = transposed(); } T *data() { return m[0]; } const T *data() const { return m[0]; } T& operator()(int row, int column) { return m[row-1][column-1]; } T operator()(int row, int column) const { return m[row-1][column-1]; } Matrix& operator=(const Matrix& other) = default; template Matrix& operator=(const std::initializer_list& values); template Matrix& operator=(const U *values); Matrix& operator+=(const Matrix& other); Matrix& operator-=(const Matrix& other); Matrix& operator*=(T factor); Matrix& operator/=(T divisor); bool operator==(const Matrix& other) const; bool operator!=(const Matrix& other) const; private: T m[N][M]; }; template void Matrix::setIdentity() { for(int i=0;i bool Matrix::isIdentity() const { for(int i=0;i void Matrix::fill(T value) { for(int i=0;i Matrix Matrix::transposed() const { Matrix result(1); for(int i=0;i template Matrix& Matrix::operator=(const std::initializer_list& values) { auto it = values.begin(); for(int i=0;i template Matrix& Matrix::operator=(const U *values) { for(int i=0;i Matrix& Matrix::operator+=(const Matrix& other) { for(int i=0;i Matrix& Matrix::operator-=(const Matrix& other) { for(int i=0;i Matrix& Matrix::operator*=(T factor) { for(int i=0;i Matrix& Matrix::operator/=(T divisor) { for(int i=0;i bool Matrix::operator==(const Matrix& other) const { for(int i=0;i bool Matrix::operator!=(const Matrix& other) const { return !(*this == other); } template std::ostream& operator<<(std::ostream& out, const Matrix& mat) { for(int i=1;i<=N;++i) { for(int j=1;j<=M;++j) { out << mat(i,j); if(j != M) out << " "; } out << "\n"; } return out; } template std::istream& operator>>(std::istream& in, Matrix& mat) { for(int i=0;i> mat(i,j); return in; } // faster comparing for 3x3 matrixes template<> inline bool Matrix<3,3,float>::operator==(const Matrix<3,3,float>& other) const { return m[0][0] == other.m[0][0] && m[1][1] == other.m[1][1] && m[2][1] == other.m[2][1] && m[2][0] == other.m[2][0] && m[1][2] == other.m[1][2] && m[0][2] == other.m[0][2] && m[1][0] == other.m[1][0] && m[0][1] == other.m[0][1] && m[2][2] == other.m[2][2]; } template Matrix operator*(const Matrix& a, const Matrix& b) { static_assert(N==P, "N==P"); Matrix c(1); for(int i=1;i<=M;++i) { for(int j=1;j<=Q;++j) { T sum = 0; for(int k=1;k<=N;++k) sum += a(i,k) * b(k,j); c(i,j) = sum; } } return c; } template Matrix operator+(const Matrix& a, const Matrix& b) { Matrix c(a); c += b; return c; } template Matrix operator-(const Matrix& a, const Matrix& b) { Matrix c(a); c -= b; return c; } template Matrix operator*(const Matrix& a, float b) { Matrix c(a); c *= b; return c; } template Matrix operator/(const Matrix& a, float b) { Matrix c = a; c /= b; return c; } typedef Matrix<4,4> Matrix4x4; typedef Matrix<3,3> Matrix3x3; typedef Matrix<2,2> Matrix2x2; typedef Matrix4x4 Matrix4; typedef Matrix3x3 Matrix3; typedef Matrix2x2 Matrix2; #endif