1 /* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef BASE_GEOMETRY_MATRIX4_H 17 #define BASE_GEOMETRY_MATRIX4_H 18 #include <vector> 19 #include "point.h" 20 21 namespace OHOS::uitest { 22 class Matrix4N; 23 class MatrixN4; 24 class Matrix4 { 25 public: 26 // Matrix dimension is 4X4. 27 static constexpr int32_t DIMENSION = 4; 28 // Create an identity matrix. 29 static Matrix4 CreateIdentity(); 30 // Multiplies this matrix by another that translates coordinates by the vector (x, y, z). 31 static Matrix4 CreateTranslate(double x, double y, double z); 32 // Multiplies this matrix by another that scales coordinates by the vector (x, y, z). 33 static Matrix4 CreateScale(double x, double y, double z); 34 35 static Matrix4 CreateMatrix2D(double m00, double m10, double m01, double m11, double m03, double m13); 36 // Multiplies this matrix by another that skew through angle degrees. 37 static Matrix4 CreateSkew(double x, double y); 38 // Create an perspective matrix, the distance value represents the distance between the user and the z=0 plane. not 39 // support percent 40 static Matrix4 CreatePerspective(double distance); 41 // Returns the inverse of this matrix. Returns the identity if this matrix cannot be inverted; 42 static Matrix4 Invert(const Matrix4& matrix); 43 44 Matrix4(); 45 Matrix4(const Matrix4& matrix); 46 Matrix4( 47 double m00, double m01, double m02, double m03, 48 double m10, double m11, double m12, double m13, 49 double m20, double m21, double m22, double m23, 50 double m30, double m31, double m32, double m33); 51 ~Matrix4() = default; 52 void SetEntry(int32_t row, int32_t col, double value); 53 bool IsIdentityMatrix() const; 54 static int32_t Count(); 55 56 bool operator==(const Matrix4& matrix) const; 57 Matrix4 operator*(double num); 58 Matrix4 operator*(const Matrix4& matrix); 59 60 Matrix4N operator*(const Matrix4N& matrix) const; 61 62 // Transform point by the matrix 63 Point operator*(const Point& point); 64 Matrix4& operator=(const Matrix4& matrix); 65 double operator[](int32_t index) const; Get(int32_t row,int32_t col)66 inline double Get(int32_t row, int32_t col) const 67 { 68 DCHECK((unsigned)row < DIMENSION); 69 DCHECK((unsigned)col < DIMENSION); 70 return matrix4x4_[col][row]; 71 } Set(int32_t row,int32_t col,double value)72 inline void Set(int32_t row, int32_t col, double value) 73 { 74 DCHECK((unsigned)row < DIMENSION); 75 DCHECK((unsigned)col < DIMENSION); 76 matrix4x4_[col][row] = value; 77 } 78 double Determinant() const; 79 void Transpose(); 80 void ScaleMapping(const double src[DIMENSION], double dst[DIMENSION]) const; 81 inline void ScaleMapping(double vec[DIMENSION], int length = DIMENSION) const 82 { 83 if (length == DIMENSION) { 84 this->ScaleMapping(vec, vec); 85 } 86 } 87 std::string ToString() const; 88 89 private: 90 static Matrix4 CreateInvert(const Matrix4& matrix); 91 double operator()(int32_t row, int32_t col) const; 92 93 double matrix4x4_[DIMENSION][DIMENSION] = { 94 { 0.0f, 0.0f, 0.0f, 0.0f }, 95 { 0.0f, 0.0f, 0.0f, 0.0f }, 96 { 0.0f, 0.0f, 0.0f, 0.0f }, 97 { 0.0f, 0.0f, 0.0f, 0.0f }, 98 }; 99 }; 100 101 class Matrix4N { 102 public: 103 // Matrix dimension is 4X4. 104 static constexpr int32_t DIMENSION = 4; 105 106 explicit Matrix4N(int32_t columns); 107 ~Matrix4N() = default; 108 GetColNum()109 inline int32_t GetColNum() const 110 { 111 return columns_; 112 } 113 114 bool SetEntry(int32_t row, int32_t col, double value); 115 116 inline Matrix4N& operator*(double num) 117 { 118 for (auto& vector : matrix4n_) { 119 std::for_each(vector.begin(), vector.end(), [num](auto& item) { item = item * num; }); 120 } 121 return *this; 122 } 123 124 // Make sure that the rows of matrixN4 is equal than the columns of matrix4N. 125 Matrix4 operator*(const MatrixN4& matrix) const; 126 127 // Make sure that the value of index is less than 4. 128 inline std::vector<double>& operator[](int32_t index) 129 { 130 return matrix4n_[index]; 131 } 132 133 // Make sure that the value of index is less than 4. 134 inline const std::vector<double>& operator[](int32_t index) const 135 { 136 return matrix4n_[index]; 137 } 138 139 // Make sure that the value of row is less than 4 and col is less than columns. operator()140 inline double operator()(int32_t row, int32_t col) const 141 { 142 return matrix4n_[row][col]; 143 } 144 145 MatrixN4 Transpose() const; 146 147 // Make sure that the vector size is equal than column. 148 std::vector<double> ScaleMapping(const std::vector<double>& src) const; 149 150 // Make sure that the vector size is equal than column. 151 bool ScaleMapping(const std::vector<double>& src, std::vector<double>& result) const; 152 153 private: 154 std::vector<std::vector<double>> matrix4n_; 155 int32_t columns_ = 0; 156 }; 157 158 class MatrixN4 { 159 public: 160 // Matrix dimension is 4XN. 161 static constexpr int32_t DIMENSION = 4; 162 163 explicit MatrixN4(int32_t rows); 164 ~MatrixN4() = default; 165 GetRowNum()166 inline int32_t GetRowNum() const 167 { 168 return rows_; 169 } 170 171 bool SetEntry(int32_t row, int32_t col, double value); 172 173 inline MatrixN4& operator*(double num) 174 { 175 for (auto& vector : matrixn4_) { 176 std::for_each(vector.begin(), vector.end(), [num](auto& item) { item = item * num; }); 177 } 178 return *this; 179 } 180 181 // Make sure that the value of index is less than rows. 182 inline std::vector<double>& operator[](int32_t index) 183 { 184 return matrixn4_[index]; 185 } 186 187 // Make sure that the value of index is less than rows. 188 inline const std::vector<double>& operator[](int32_t index) const 189 { 190 return matrixn4_[index]; 191 } 192 193 // Make sure that the value of row is less than rows and col is less than 4. operator()194 inline double operator()(int32_t row, int32_t col) const 195 { 196 return matrixn4_[row][col]; 197 } 198 199 Matrix4N Transpose() const; 200 201 // Make sure that the vector size is equal than column. 202 std::vector<double> ScaleMapping(const std::vector<double>& src) const; 203 204 private: 205 std::vector<std::vector<double>> matrixn4_; 206 int32_t rows_ = 0; 207 }; 208 } // namespace OHOS::uitest 209 #endif // MATRIX4_H 210