xref: /aosp_15_r20/external/libchrome/ui/gfx/geometry/matrix3_f.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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