1 /* 2 * Copyright (c) 2021-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 FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_MATRIX4_H 17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_MATRIX4_H 18 19 #include <vector> 20 21 #include "base/geometry/point.h" 22 23 namespace OHOS::Ace { 24 25 class Matrix4N; 26 class MatrixN4; 27 28 class ACE_EXPORT Matrix4 { 29 public: 30 // Matrix dimension is 4X4. 31 static constexpr int32_t DIMENSION = 4; 32 // Create an identity matrix. 33 static Matrix4 CreateIdentity(); 34 // Multiplies this matrix by another that translates coordinates by the vector (x, y, z). 35 static Matrix4 CreateTranslate(double x, double y, double z); 36 // Multiplies this matrix by another that scales coordinates by the vector (x, y, z). 37 static Matrix4 CreateScale(double x, double y, double z); 38 // Multiplies this matrix by another that rotates coordinates through angle degrees about the vector (dx, dy, dz). 39 static Matrix4 CreateRotate(double angle, double dx, double dy, double dz); 40 41 static Matrix4 CreateMatrix2D(double m00, double m10, double m01, double m11, double m03, double m13); 42 // Multiplies this matrix by another that skew through angle degrees. 43 static Matrix4 CreateSkew(double x, double y); 44 // Create an perspective matrix, the distance value represents the distance between the user and the z=0 plane. not 45 // support percent 46 static Matrix4 CreatePerspective(double distance); 47 // Returns the inverse of this matrix. Returns the identity if this matrix cannot be inverted; 48 static Matrix4 Invert(const Matrix4& matrix); 49 50 Matrix4(); 51 Matrix4(const Matrix4& matrix); 52 Matrix4( 53 double m00, double m01, double m02, double m03, 54 double m10, double m11, double m12, double m13, 55 double m20, double m21, double m22, double m23, 56 double m30, double m31, double m32, double m33); 57 ~Matrix4() = default; 58 void SetScale(double x, double y, double z); 59 double GetScaleX() const; 60 double GetScaleY() const; 61 void Rotate(double angle, double dx, double dy, double dz); 62 void SetEntry(int32_t row, int32_t col, double value); 63 bool IsIdentityMatrix() const; 64 int32_t Count() const; 65 66 bool operator==(const Matrix4& matrix) const; 67 Matrix4 operator*(double num); 68 Matrix4 operator*(const Matrix4& matrix); 69 70 Matrix4N operator*(const Matrix4N& matrix) const; 71 72 // Transform point by the matrix 73 Point operator*(const Point& point); 74 Matrix4& operator=(const Matrix4& matrix); 75 double operator[](int32_t index) const; Get(int32_t row,int32_t col)76 inline double Get(int32_t row, int32_t col) const 77 { 78 ACE_DCHECK((unsigned)row < DIMENSION); 79 ACE_DCHECK((unsigned)col < DIMENSION); 80 return matrix4x4_[col][row]; 81 } Set(int32_t row,int32_t col,double value)82 inline void Set(int32_t row, int32_t col, double value) 83 { 84 ACE_DCHECK((unsigned)row < DIMENSION); 85 ACE_DCHECK((unsigned)col < DIMENSION); 86 matrix4x4_[col][row] = value; 87 } 88 double Determinant() const; 89 void Transpose(); 90 void MapScalars(const double src[DIMENSION], double dst[DIMENSION]) const; 91 inline void MapScalars(double vec[DIMENSION], int length = DIMENSION) const 92 { 93 if (length == DIMENSION) { 94 this->MapScalars(vec, vec); 95 } 96 } 97 std::string ToString() const; 98 99 private: 100 static Matrix4 CreateInvert(const Matrix4& matrix); 101 double operator()(int32_t row, int32_t col) const; 102 103 double matrix4x4_[DIMENSION][DIMENSION] = { 104 { 0.0f, 0.0f, 0.0f, 0.0f }, 105 { 0.0f, 0.0f, 0.0f, 0.0f }, 106 { 0.0f, 0.0f, 0.0f, 0.0f }, 107 { 0.0f, 0.0f, 0.0f, 0.0f }, 108 }; 109 }; 110 111 class ACE_EXPORT Matrix4N { 112 public: 113 // Matrix dimension is 4X4. 114 static constexpr int32_t DIMENSION = 4; 115 116 explicit Matrix4N(int32_t columns); 117 ~Matrix4N() = default; 118 GetColNum()119 inline int32_t GetColNum() const 120 { 121 return columns_; 122 } 123 124 bool SetEntry(int32_t row, int32_t col, double value); 125 126 inline Matrix4N& operator*(double num) 127 { 128 for (auto& vector : matrix4n_) { 129 std::for_each(vector.begin(), vector.end(), [num](auto& item) { item = item * num; }); 130 } 131 return *this; 132 } 133 134 // Make sure that the rows of matrixN4 is equal than the columns of matrix4N. 135 Matrix4 operator*(const MatrixN4& matrix) const; 136 137 // Make sure that the value of index is less than 4. 138 inline std::vector<double>& operator[](int32_t index) 139 { 140 return matrix4n_[index]; 141 } 142 143 // Make sure that the value of index is less than 4. 144 inline const std::vector<double>& operator[](int32_t index) const 145 { 146 return matrix4n_[index]; 147 } 148 149 // Make sure that the value of row is less than 4 and col is less than columns. operator()150 inline double operator()(int32_t row, int32_t col) const 151 { 152 return matrix4n_[row][col]; 153 } 154 155 MatrixN4 Transpose() const; 156 157 // Make sure that the vector size is equal than column. 158 std::vector<double> MapScalars(const std::vector<double>& src) const; 159 160 // Make sure that the vector size is equal than column. 161 bool MapScalars(const std::vector<double>& src, std::vector<double>& result) const; 162 163 private: 164 std::vector<std::vector<double>> matrix4n_; 165 int32_t columns_ = 0; 166 }; 167 168 class ACE_EXPORT MatrixN4 { 169 public: 170 // Matrix dimension is 4XN. 171 static constexpr int32_t DIMENSION = 4; 172 173 explicit MatrixN4(int32_t rows); 174 ~MatrixN4() = default; 175 GetRowNum()176 inline int32_t GetRowNum() const 177 { 178 return rows_; 179 } 180 181 bool SetEntry(int32_t row, int32_t col, double value); 182 183 inline MatrixN4& operator*(double num) 184 { 185 for (auto& vector : matrixn4_) { 186 std::for_each(vector.begin(), vector.end(), [num](auto& item) { item = item * num; }); 187 } 188 return *this; 189 } 190 191 // Make sure that the value of index is less than rows. 192 inline std::vector<double>& operator[](int32_t index) 193 { 194 return matrixn4_[index]; 195 } 196 197 // Make sure that the value of index is less than rows. 198 inline const std::vector<double>& operator[](int32_t index) const 199 { 200 return matrixn4_[index]; 201 } 202 203 // Make sure that the value of row is less than rows and col is less than 4. operator()204 inline double operator()(int32_t row, int32_t col) const 205 { 206 return matrixn4_[row][col]; 207 } 208 209 Matrix4N Transpose() const; 210 211 // Make sure that the vector size is equal than column. 212 std::vector<double> MapScalars(const std::vector<double>& src) const; 213 214 private: 215 std::vector<std::vector<double>> matrixn4_; 216 int32_t rows_ = 0; 217 }; 218 219 } // namespace OHOS::Ace 220 221 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_MATRIX4_H 222