1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker #ifndef UI_GFX_GEOMETRY_MATRIX3_F_H_ 6*635a8641SAndroid Build Coastguard Worker #define UI_GFX_GEOMETRY_MATRIX3_F_H_ 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker #include "base/logging.h" 9*635a8641SAndroid Build Coastguard Worker #include "ui/gfx/geometry/vector3d_f.h" 10*635a8641SAndroid Build Coastguard Worker 11*635a8641SAndroid Build Coastguard Worker namespace gfx { 12*635a8641SAndroid Build Coastguard Worker 13*635a8641SAndroid Build Coastguard Worker class GFX_EXPORT Matrix3F { 14*635a8641SAndroid Build Coastguard Worker public: 15*635a8641SAndroid Build Coastguard Worker ~Matrix3F(); 16*635a8641SAndroid Build Coastguard Worker 17*635a8641SAndroid Build Coastguard Worker static Matrix3F Zeros(); 18*635a8641SAndroid Build Coastguard Worker static Matrix3F Ones(); 19*635a8641SAndroid Build Coastguard Worker static Matrix3F Identity(); 20*635a8641SAndroid Build Coastguard Worker static Matrix3F FromOuterProduct(const Vector3dF& a, const Vector3dF& bt); 21*635a8641SAndroid Build Coastguard Worker 22*635a8641SAndroid Build Coastguard Worker bool IsEqual(const Matrix3F& rhs) const; 23*635a8641SAndroid Build Coastguard Worker 24*635a8641SAndroid Build Coastguard Worker // Element-wise comparison with given precision. 25*635a8641SAndroid Build Coastguard Worker bool IsNear(const Matrix3F& rhs, float precision) const; 26*635a8641SAndroid Build Coastguard Worker get(int i,int j)27*635a8641SAndroid Build Coastguard Worker float get(int i, int j) const { 28*635a8641SAndroid Build Coastguard Worker return data_[MatrixToArrayCoords(i, j)]; 29*635a8641SAndroid Build Coastguard Worker } 30*635a8641SAndroid Build Coastguard Worker set(int i,int j,float v)31*635a8641SAndroid Build Coastguard Worker void set(int i, int j, float v) { 32*635a8641SAndroid Build Coastguard Worker data_[MatrixToArrayCoords(i, j)] = v; 33*635a8641SAndroid Build Coastguard Worker } 34*635a8641SAndroid Build Coastguard Worker set(float m00,float m01,float m02,float m10,float m11,float m12,float m20,float m21,float m22)35*635a8641SAndroid Build Coastguard Worker void set(float m00, float m01, float m02, 36*635a8641SAndroid Build Coastguard Worker float m10, float m11, float m12, 37*635a8641SAndroid Build Coastguard Worker float m20, float m21, float m22) { 38*635a8641SAndroid Build Coastguard Worker data_[0] = m00; 39*635a8641SAndroid Build Coastguard Worker data_[1] = m01; 40*635a8641SAndroid Build Coastguard Worker data_[2] = m02; 41*635a8641SAndroid Build Coastguard Worker data_[3] = m10; 42*635a8641SAndroid Build Coastguard Worker data_[4] = m11; 43*635a8641SAndroid Build Coastguard Worker data_[5] = m12; 44*635a8641SAndroid Build Coastguard Worker data_[6] = m20; 45*635a8641SAndroid Build Coastguard Worker data_[7] = m21; 46*635a8641SAndroid Build Coastguard Worker data_[8] = m22; 47*635a8641SAndroid Build Coastguard Worker } 48*635a8641SAndroid Build Coastguard Worker get_row(int i)49*635a8641SAndroid Build Coastguard Worker Vector3dF get_row(int i) const { 50*635a8641SAndroid Build Coastguard Worker return Vector3dF(data_[MatrixToArrayCoords(i, 0)], 51*635a8641SAndroid Build Coastguard Worker data_[MatrixToArrayCoords(i, 1)], 52*635a8641SAndroid Build Coastguard Worker data_[MatrixToArrayCoords(i, 2)]); 53*635a8641SAndroid Build Coastguard Worker } 54*635a8641SAndroid Build Coastguard Worker get_column(int i)55*635a8641SAndroid Build Coastguard Worker Vector3dF get_column(int i) const { 56*635a8641SAndroid Build Coastguard Worker return Vector3dF( 57*635a8641SAndroid Build Coastguard Worker data_[MatrixToArrayCoords(0, i)], 58*635a8641SAndroid Build Coastguard Worker data_[MatrixToArrayCoords(1, i)], 59*635a8641SAndroid Build Coastguard Worker data_[MatrixToArrayCoords(2, i)]); 60*635a8641SAndroid Build Coastguard Worker } 61*635a8641SAndroid Build Coastguard Worker set_column(int i,const Vector3dF & c)62*635a8641SAndroid Build Coastguard Worker void set_column(int i, const Vector3dF& c) { 63*635a8641SAndroid Build Coastguard Worker data_[MatrixToArrayCoords(0, i)] = c.x(); 64*635a8641SAndroid Build Coastguard Worker data_[MatrixToArrayCoords(1, i)] = c.y(); 65*635a8641SAndroid Build Coastguard Worker data_[MatrixToArrayCoords(2, i)] = c.z(); 66*635a8641SAndroid Build Coastguard Worker } 67*635a8641SAndroid Build Coastguard Worker 68*635a8641SAndroid Build Coastguard Worker // Produces a new matrix by adding the elements of |rhs| to this matrix 69*635a8641SAndroid Build Coastguard Worker Matrix3F Add(const Matrix3F& rhs) const; 70*635a8641SAndroid Build Coastguard Worker // Produces a new matrix by subtracting elements of |rhs| from this matrix. 71*635a8641SAndroid Build Coastguard Worker Matrix3F Subtract(const Matrix3F& rhs) const; 72*635a8641SAndroid Build Coastguard Worker 73*635a8641SAndroid Build Coastguard Worker // Returns an inverse of this if the matrix is non-singular, zero (== Zero()) 74*635a8641SAndroid Build Coastguard Worker // otherwise. 75*635a8641SAndroid Build Coastguard Worker Matrix3F Inverse() const; 76*635a8641SAndroid Build Coastguard Worker 77*635a8641SAndroid Build Coastguard Worker // Returns a transpose of this matrix. 78*635a8641SAndroid Build Coastguard Worker Matrix3F Transpose() const; 79*635a8641SAndroid Build Coastguard Worker 80*635a8641SAndroid Build Coastguard Worker // Value of the determinant of the matrix. 81*635a8641SAndroid Build Coastguard Worker float Determinant() const; 82*635a8641SAndroid Build Coastguard Worker 83*635a8641SAndroid Build Coastguard Worker // Trace (sum of diagonal elements) of the matrix. Trace()84*635a8641SAndroid Build Coastguard Worker float Trace() const { 85*635a8641SAndroid Build Coastguard Worker return data_[MatrixToArrayCoords(0, 0)] + 86*635a8641SAndroid Build Coastguard Worker data_[MatrixToArrayCoords(1, 1)] + 87*635a8641SAndroid Build Coastguard Worker data_[MatrixToArrayCoords(2, 2)]; 88*635a8641SAndroid Build Coastguard Worker } 89*635a8641SAndroid Build Coastguard Worker 90*635a8641SAndroid Build Coastguard Worker // Compute eigenvalues and (optionally) normalized eigenvectors of 91*635a8641SAndroid Build Coastguard Worker // a positive defnite matrix *this. Eigenvectors are computed only if 92*635a8641SAndroid Build Coastguard Worker // non-null |eigenvectors| matrix is passed. If it is NULL, the routine 93*635a8641SAndroid Build Coastguard Worker // will not attempt to compute eigenvectors but will still return eigenvalues 94*635a8641SAndroid Build Coastguard Worker // if they can be computed. 95*635a8641SAndroid Build Coastguard Worker // If eigenvalues cannot be computed (the matrix does not meet constraints) 96*635a8641SAndroid Build Coastguard Worker // the 0-vector is returned. Note that to retrieve eigenvalues, the matrix 97*635a8641SAndroid Build Coastguard Worker // only needs to be symmetric while eigenvectors require it to be 98*635a8641SAndroid Build Coastguard Worker // positive-definite. Passing a non-positive definite matrix will result in 99*635a8641SAndroid Build Coastguard Worker // NaNs in vectors which cannot be computed. 100*635a8641SAndroid Build Coastguard Worker // Eigenvectors are placed as column in |eigenvectors| in order corresponding 101*635a8641SAndroid Build Coastguard Worker // to eigenvalues. 102*635a8641SAndroid Build Coastguard Worker Vector3dF SolveEigenproblem(Matrix3F* eigenvectors) const; 103*635a8641SAndroid Build Coastguard Worker 104*635a8641SAndroid Build Coastguard Worker std::string ToString() const; 105*635a8641SAndroid Build Coastguard Worker 106*635a8641SAndroid Build Coastguard Worker private: 107*635a8641SAndroid Build Coastguard Worker Matrix3F(); // Uninitialized default. 108*635a8641SAndroid Build Coastguard Worker MatrixToArrayCoords(int i,int j)109*635a8641SAndroid Build Coastguard Worker static int MatrixToArrayCoords(int i, int j) { 110*635a8641SAndroid Build Coastguard Worker DCHECK(i >= 0 && i < 3); 111*635a8641SAndroid Build Coastguard Worker DCHECK(j >= 0 && j < 3); 112*635a8641SAndroid Build Coastguard Worker return i * 3 + j; 113*635a8641SAndroid Build Coastguard Worker } 114*635a8641SAndroid Build Coastguard Worker 115*635a8641SAndroid Build Coastguard Worker float data_[9]; 116*635a8641SAndroid Build Coastguard Worker }; 117*635a8641SAndroid Build Coastguard Worker 118*635a8641SAndroid Build Coastguard Worker inline bool operator==(const Matrix3F& lhs, const Matrix3F& rhs) { 119*635a8641SAndroid Build Coastguard Worker return lhs.IsEqual(rhs); 120*635a8641SAndroid Build Coastguard Worker } 121*635a8641SAndroid Build Coastguard Worker 122*635a8641SAndroid Build Coastguard Worker // Matrix addition. Produces a new matrix by adding the corresponding elements 123*635a8641SAndroid Build Coastguard Worker // together. 124*635a8641SAndroid Build Coastguard Worker inline Matrix3F operator+(const Matrix3F& lhs, const Matrix3F& rhs) { 125*635a8641SAndroid Build Coastguard Worker return lhs.Add(rhs); 126*635a8641SAndroid Build Coastguard Worker } 127*635a8641SAndroid Build Coastguard Worker 128*635a8641SAndroid Build Coastguard Worker // Matrix subtraction. Produces a new matrix by subtracting elements of rhs 129*635a8641SAndroid Build Coastguard Worker // from corresponding elements of lhs. 130*635a8641SAndroid Build Coastguard Worker inline Matrix3F operator-(const Matrix3F& lhs, const Matrix3F& rhs) { 131*635a8641SAndroid Build Coastguard Worker return lhs.Subtract(rhs); 132*635a8641SAndroid Build Coastguard Worker } 133*635a8641SAndroid Build Coastguard Worker 134*635a8641SAndroid Build Coastguard Worker GFX_EXPORT Matrix3F MatrixProduct(const Matrix3F& lhs, const Matrix3F& rhs); 135*635a8641SAndroid Build Coastguard Worker GFX_EXPORT Vector3dF MatrixProduct(const Matrix3F& lhs, const Vector3dF& rhs); 136*635a8641SAndroid Build Coastguard Worker 137*635a8641SAndroid Build Coastguard Worker } // namespace gfx 138*635a8641SAndroid Build Coastguard Worker 139*635a8641SAndroid Build Coastguard Worker #endif // UI_GFX_GEOMETRY_MATRIX3_F_H_ 140