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