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