• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "base/geometry/matrix4.h"
17 #include "core/pipeline/base/constants.h"
18 
19 namespace OHOS::Ace {
20 namespace {
21 constexpr int32_t MATRIX_LENGTH = Matrix4::DIMENSION * Matrix4::DIMENSION;
22 constexpr double ANGLE_UNIT = 0.017453f; // PI / 180
23 
IsEqual(const double & left,const double & right)24 inline bool IsEqual(const double& left, const double& right)
25 {
26     constexpr double epsilon = 0.0001;
27     return NearEqual(left, right, epsilon);
28 }
29 
30 } // namespace
31 
CreateIdentity()32 Matrix4 Matrix4::CreateIdentity()
33 {
34     return Matrix4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
35 }
36 
CreateTranslate(double x,double y,double z)37 Matrix4 Matrix4::CreateTranslate(double x, double y, double z)
38 {
39     return Matrix4(1.0f, 0.0f, 0.0f, x, 0.0f, 1.0f, 0.0f, y, 0.0f, 0.0f, 1.0f, z, 0.0f, 0.0f, 0.0f, 1.0f);
40 }
41 
CreateScale(double x,double y,double z)42 Matrix4 Matrix4::CreateScale(double x, double y, double z)
43 {
44     return Matrix4(x, 0.0f, 0.0f, 0.0f, 0.0f, y, 0.0f, 0.0f, 0.0f, 0.0f, z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
45 }
46 
CreateRotate(double angle,double dx,double dy,double dz)47 Matrix4 Matrix4::CreateRotate(double angle, double dx, double dy, double dz)
48 {
49     // (x,y,z) need normalize
50     double sum = dx * dx + dy * dy + dz * dz;
51     if (NearZero(sum)) {
52         return Matrix4::CreateIdentity();
53     }
54 
55     double x = dx / sqrt(sum);
56     double y = dy / sqrt(sum);
57     double z = dz / sqrt(sum);
58     double redian = static_cast<double>(angle * (ACE_PI / 180.0f));
59     double cosValue = cosf(redian);
60     double sinValue = sinf(redian);
61 
62     return Matrix4(cosValue + (x * x * (1.0f - cosValue)), (x * y * (1.0f - cosValue)) - (z * sinValue),
63         (x * z * (1.0f - cosValue)) + (y * sinValue), 0.0f, (y * x * (1.0f - cosValue)) + (z * sinValue),
64         cosValue + (y * y * (1.0f - cosValue)), (y * z * (1.0f - cosValue)) - (x * sinValue), 0.0f,
65         (z * x * (1.0f - cosValue)) - (y * sinValue), (z * y * (1.0f - cosValue)) + (x * sinValue),
66         cosValue + (z * z * (1.0f - cosValue)), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
67 }
68 
CreateMatrix2D(double m00,double m10,double m01,double m11,double m03,double m13)69 Matrix4 Matrix4::CreateMatrix2D(double m00, double m10, double m01, double m11, double m03, double m13)
70 {
71     return Matrix4(m00, m01, 0.0f, m03, m10, m11, 0.0f, m13, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
72 }
73 
CreateSkew(double x,double y)74 Matrix4 Matrix4::CreateSkew(double x, double y)
75 {
76     return Matrix4(1.0f, std::tan(x * ANGLE_UNIT), 0.0f, 0.0f, std::tan(y * ANGLE_UNIT), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
77         1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
78 }
79 
CreateFactorSkew(double x,double y)80 Matrix4 Matrix4::CreateFactorSkew(double x, double y)
81 {
82     return Matrix4(1.0f, x, 0.0f, 0.0f, y, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
83         1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
84 }
85 
CreateFactorPerspective(double x,double y)86 Matrix4 Matrix4::CreateFactorPerspective(double x, double y)
87 {
88     return Matrix4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
89         1.0f, 0.0f, x, y, 0.0f, 1.0f);
90 }
91 
CreatePerspective(double distance)92 Matrix4 Matrix4::CreatePerspective(double distance)
93 {
94     auto result = CreateIdentity();
95     if (GreatNotEqual(distance, 0.0f)) {
96         result.matrix4x4_[2][3] = -1.0f / distance;
97     }
98     return result;
99 }
100 
Invert(const Matrix4 & matrix)101 Matrix4 Matrix4::Invert(const Matrix4& matrix)
102 {
103     Matrix4 inverted = CreateInvert(matrix);
104     double determinant = matrix(0, 0) * inverted(0, 0) + matrix(0, 1) * inverted(1, 0) + matrix(0, 2) * inverted(2, 0) +
105                          matrix(0, 3) * inverted(3, 0);
106     if (!NearZero(determinant)) {
107         inverted = inverted * (1.0f / determinant);
108     } else {
109         inverted = CreateIdentity();
110     }
111 
112     return inverted;
113 }
114 
QuaternionToMatrix(double x,double y,double z,double w)115 Matrix4 Matrix4::QuaternionToMatrix(double x, double y, double z, double w)
116 {
117     double norm = std::sqrt(w * w + x * x + y * y + z * z);
118     if (LessOrEqual(norm, 0.0f)) {
119         return Matrix4();
120     }
121     w /= norm;
122     x /= norm;
123     y /= norm;
124     z /= norm;
125 
126     // Quaternion to matrix operation wiki:reference/apis-arkui/js-apis-matrix4.md.
127     return Matrix4(1.0 - 2.0 * (y * y + z * z), 2.0 * (x * y - w * z), 2.0 * (x * z + w * y), 0.0,
128         2.0 * (x * y + w * z), 1.0 - 2.0 * (x * x + z * z), 2.0 * (y * z - w * x), 0.0,
129         2.0 * (x * z - w * y), 2.0 * (y * z + w * x), 1.0 - 2.0 * (x * x + y * y), 0.0,
130         0.0, 0.0, 0.0, 1.0);
131 }
132 
Matrix4()133 Matrix4::Matrix4()
134     : Matrix4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f)
135 {}
136 
Matrix4(const Matrix4 & matrix)137 Matrix4::Matrix4(const Matrix4& matrix)
138 {
139     std::copy_n(&matrix.matrix4x4_[0][0], MATRIX_LENGTH, &matrix4x4_[0][0]);
140 }
141 
Matrix4(double m00,double m01,double m02,double m03,double m10,double m11,double m12,double m13,double m20,double m21,double m22,double m23,double m30,double m31,double m32,double m33)142 Matrix4::Matrix4(double m00, double m01, double m02, double m03, double m10, double m11, double m12, double m13,
143     double m20, double m21, double m22, double m23, double m30, double m31, double m32, double m33)
144 {
145     matrix4x4_[0][0] = m00;
146     matrix4x4_[1][0] = m01;
147     matrix4x4_[2][0] = m02;
148     matrix4x4_[3][0] = m03;
149     matrix4x4_[0][1] = m10;
150     matrix4x4_[1][1] = m11;
151     matrix4x4_[2][1] = m12;
152     matrix4x4_[3][1] = m13;
153     matrix4x4_[0][2] = m20;
154     matrix4x4_[1][2] = m21;
155     matrix4x4_[2][2] = m22;
156     matrix4x4_[3][2] = m23;
157     matrix4x4_[0][3] = m30;
158     matrix4x4_[1][3] = m31;
159     matrix4x4_[2][3] = m32;
160     matrix4x4_[3][3] = m33;
161 }
162 
SetScale(double x,double y,double z)163 void Matrix4::SetScale(double x, double y, double z)
164 {
165     // The 4X4 matrix scale index is [0][0], [1][1], [2][2], [3][3].
166     matrix4x4_[0][0] = x;
167     matrix4x4_[1][1] = y;
168     matrix4x4_[2][2] = z;
169     matrix4x4_[3][3] = 1.0f;
170 }
171 
GetScaleX() const172 double Matrix4::GetScaleX() const
173 {
174     return matrix4x4_[0][0];
175 }
176 
GetScaleY() const177 double Matrix4::GetScaleY() const
178 {
179     return matrix4x4_[1][1];
180 }
181 
SetEntry(int32_t row,int32_t col,double value)182 void Matrix4::SetEntry(int32_t row, int32_t col, double value)
183 {
184     if ((row < 0 || row >= DIMENSION) || (col < 0 || col >= DIMENSION)) {
185         return;
186     }
187     matrix4x4_[row][col] = value;
188 }
189 
IsIdentityMatrix() const190 bool Matrix4::IsIdentityMatrix() const
191 {
192     return *this == CreateIdentity();
193 }
194 
Rotate(double angle,double dx,double dy,double dz)195 void Matrix4::Rotate(double angle, double dx, double dy, double dz)
196 {
197     Matrix4 transform = *this;
198     *this = transform * CreateRotate(angle, dx, dy, dz);
199 }
200 
Count() const201 int32_t Matrix4::Count() const
202 {
203     return MATRIX_LENGTH;
204 }
205 
CreateInvert(const Matrix4 & matrix)206 Matrix4 Matrix4::CreateInvert(const Matrix4& matrix)
207 {
208     return Matrix4(
209         matrix(1, 1) * matrix(2, 2) * matrix(3, 3) - matrix(1, 1) * matrix(2, 3) * matrix(3, 2) -
210             matrix(2, 1) * matrix(1, 2) * matrix(3, 3) + matrix(2, 1) * matrix(1, 3) * matrix(3, 2) +
211             matrix(3, 1) * matrix(1, 2) * matrix(2, 3) - matrix(3, 1) * matrix(1, 3) * matrix(2, 2),
212         -matrix(1, 0) * matrix(2, 2) * matrix(3, 3) + matrix(1, 0) * matrix(2, 3) * matrix(3, 2) +
213             matrix(2, 0) * matrix(1, 2) * matrix(3, 3) - matrix(2, 0) * matrix(1, 3) * matrix(3, 2) -
214             matrix(3, 0) * matrix(1, 2) * matrix(2, 3) + matrix(3, 0) * matrix(1, 3) * matrix(2, 2),
215         matrix(1, 0) * matrix(2, 1) * matrix(3, 3) - matrix(1, 0) * matrix(2, 3) * matrix(3, 1) -
216             matrix(2, 0) * matrix(1, 1) * matrix(3, 3) + matrix(2, 0) * matrix(1, 3) * matrix(3, 1) +
217             matrix(3, 0) * matrix(1, 1) * matrix(2, 3) - matrix(3, 0) * matrix(1, 3) * matrix(2, 1),
218         -matrix(1, 0) * matrix(2, 1) * matrix(3, 2) + matrix(1, 0) * matrix(2, 2) * matrix(3, 1) +
219             matrix(2, 0) * matrix(1, 1) * matrix(3, 2) - matrix(2, 0) * matrix(1, 2) * matrix(3, 1) -
220             matrix(3, 0) * matrix(1, 1) * matrix(2, 2) + matrix(3, 0) * matrix(1, 2) * matrix(2, 1),
221         -matrix(0, 1) * matrix(2, 2) * matrix(3, 3) + matrix(0, 1) * matrix(2, 3) * matrix(3, 2) +
222             matrix(2, 1) * matrix(0, 2) * matrix(3, 3) - matrix(2, 1) * matrix(0, 3) * matrix(3, 2) -
223             matrix(3, 1) * matrix(0, 2) * matrix(2, 3) + matrix(3, 1) * matrix(0, 3) * matrix(2, 2),
224         matrix(0, 0) * matrix(2, 2) * matrix(3, 3) - matrix(0, 0) * matrix(2, 3) * matrix(3, 2) -
225             matrix(2, 0) * matrix(0, 2) * matrix(3, 3) + matrix(2, 0) * matrix(0, 3) * matrix(3, 2) +
226             matrix(3, 0) * matrix(0, 2) * matrix(2, 3) - matrix(3, 0) * matrix(0, 3) * matrix(2, 2),
227         -matrix(0, 0) * matrix(2, 1) * matrix(3, 3) + matrix(0, 0) * matrix(2, 3) * matrix(3, 1) +
228             matrix(2, 0) * matrix(0, 1) * matrix(3, 3) - matrix(2, 0) * matrix(0, 3) * matrix(3, 1) -
229             matrix(3, 0) * matrix(0, 1) * matrix(2, 3) + matrix(3, 0) * matrix(0, 3) * matrix(2, 1),
230         matrix(0, 0) * matrix(2, 1) * matrix(3, 2) - matrix(0, 0) * matrix(2, 2) * matrix(3, 1) -
231             matrix(2, 0) * matrix(0, 1) * matrix(3, 2) + matrix(2, 0) * matrix(0, 2) * matrix(3, 1) +
232             matrix(3, 0) * matrix(0, 1) * matrix(2, 2) - matrix(3, 0) * matrix(0, 2) * matrix(2, 1),
233         matrix(0, 1) * matrix(1, 2) * matrix(3, 3) - matrix(0, 1) * matrix(1, 3) * matrix(3, 2) -
234             matrix(1, 1) * matrix(0, 2) * matrix(3, 3) + matrix(1, 1) * matrix(0, 3) * matrix(3, 2) +
235             matrix(3, 1) * matrix(0, 2) * matrix(1, 3) - matrix(3, 1) * matrix(0, 3) * matrix(1, 2),
236         -matrix(0, 0) * matrix(1, 2) * matrix(3, 3) + matrix(0, 0) * matrix(1, 3) * matrix(3, 2) +
237             matrix(1, 0) * matrix(0, 2) * matrix(3, 3) - matrix(1, 0) * matrix(0, 3) * matrix(3, 2) -
238             matrix(3, 0) * matrix(0, 2) * matrix(1, 3) + matrix(3, 0) * matrix(0, 3) * matrix(1, 2),
239         matrix(0, 0) * matrix(1, 1) * matrix(3, 3) - matrix(0, 0) * matrix(1, 3) * matrix(3, 1) -
240             matrix(1, 0) * matrix(0, 1) * matrix(3, 3) + matrix(1, 0) * matrix(0, 3) * matrix(3, 1) +
241             matrix(3, 0) * matrix(0, 1) * matrix(1, 3) - matrix(3, 0) * matrix(0, 3) * matrix(1, 1),
242         -matrix(0, 0) * matrix(1, 1) * matrix(3, 2) + matrix(0, 0) * matrix(1, 2) * matrix(3, 1) +
243             matrix(1, 0) * matrix(0, 1) * matrix(3, 2) - matrix(1, 0) * matrix(0, 2) * matrix(3, 1) -
244             matrix(3, 0) * matrix(0, 1) * matrix(1, 2) + matrix(3, 0) * matrix(0, 2) * matrix(1, 1),
245         -matrix(0, 1) * matrix(1, 2) * matrix(2, 3) + matrix(0, 1) * matrix(1, 3) * matrix(2, 2) +
246             matrix(1, 1) * matrix(0, 2) * matrix(2, 3) - matrix(1, 1) * matrix(0, 3) * matrix(2, 2) -
247             matrix(2, 1) * matrix(0, 2) * matrix(1, 3) + matrix(2, 1) * matrix(0, 3) * matrix(1, 2),
248         matrix(0, 0) * matrix(1, 2) * matrix(2, 3) - matrix(0, 0) * matrix(1, 3) * matrix(2, 2) -
249             matrix(1, 0) * matrix(0, 2) * matrix(2, 3) + matrix(1, 0) * matrix(0, 3) * matrix(2, 2) +
250             matrix(2, 0) * matrix(0, 2) * matrix(1, 3) - matrix(2, 0) * matrix(0, 3) * matrix(1, 2),
251         -matrix(0, 0) * matrix(1, 1) * matrix(2, 3) + matrix(0, 0) * matrix(1, 3) * matrix(2, 1) +
252             matrix(1, 0) * matrix(0, 1) * matrix(2, 3) - matrix(1, 0) * matrix(0, 3) * matrix(2, 1) -
253             matrix(2, 0) * matrix(0, 1) * matrix(1, 3) + matrix(2, 0) * matrix(0, 3) * matrix(1, 1),
254         matrix(0, 0) * matrix(1, 1) * matrix(2, 2) - matrix(0, 0) * matrix(1, 2) * matrix(2, 1) -
255             matrix(1, 0) * matrix(0, 1) * matrix(2, 2) + matrix(1, 0) * matrix(0, 2) * matrix(2, 1) +
256             matrix(2, 0) * matrix(0, 1) * matrix(1, 2) - matrix(2, 0) * matrix(0, 2) * matrix(1, 1));
257 }
258 
operator ==(const Matrix4 & matrix) const259 bool Matrix4::operator==(const Matrix4& matrix) const
260 {
261     return std::equal(&matrix4x4_[0][0], &matrix4x4_[0][0] + MATRIX_LENGTH, &matrix.matrix4x4_[0][0], IsEqual);
262 }
263 
operator *(double num)264 Matrix4 Matrix4::operator*(double num)
265 {
266     Matrix4 ret(*this);
267     auto function = [num](double& v) { v *= num; };
268     auto it = &ret.matrix4x4_[0][0];
269     for (int32_t i = 0; i < MATRIX_LENGTH; ++it, ++i) {
270         function(*it);
271     }
272     return ret;
273 }
274 
operator *(const Matrix4 & matrix)275 Matrix4 Matrix4::operator*(const Matrix4& matrix)
276 {
277     return Matrix4(
278         matrix4x4_[0][0] * matrix(0, 0) + matrix4x4_[1][0] * matrix(0, 1) + matrix4x4_[2][0] * matrix(0, 2) +
279             matrix4x4_[3][0] * matrix(0, 3),
280         matrix4x4_[0][0] * matrix(1, 0) + matrix4x4_[1][0] * matrix(1, 1) + matrix4x4_[2][0] * matrix(1, 2) +
281             matrix4x4_[3][0] * matrix(1, 3),
282         matrix4x4_[0][0] * matrix(2, 0) + matrix4x4_[1][0] * matrix(2, 1) + matrix4x4_[2][0] * matrix(2, 2) +
283             matrix4x4_[3][0] * matrix(2, 3),
284         matrix4x4_[0][0] * matrix(3, 0) + matrix4x4_[1][0] * matrix(3, 1) + matrix4x4_[2][0] * matrix(3, 2) +
285             matrix4x4_[3][0] * matrix(3, 3),
286         matrix4x4_[0][1] * matrix(0, 0) + matrix4x4_[1][1] * matrix(0, 1) + matrix4x4_[2][1] * matrix(0, 2) +
287             matrix4x4_[3][1] * matrix(0, 3),
288         matrix4x4_[0][1] * matrix(1, 0) + matrix4x4_[1][1] * matrix(1, 1) + matrix4x4_[2][1] * matrix(1, 2) +
289             matrix4x4_[3][1] * matrix(1, 3),
290         matrix4x4_[0][1] * matrix(2, 0) + matrix4x4_[1][1] * matrix(2, 1) + matrix4x4_[2][1] * matrix(2, 2) +
291             matrix4x4_[3][1] * matrix(2, 3),
292         matrix4x4_[0][1] * matrix(3, 0) + matrix4x4_[1][1] * matrix(3, 1) + matrix4x4_[2][1] * matrix(3, 2) +
293             matrix4x4_[3][1] * matrix(3, 3),
294         matrix4x4_[0][2] * matrix(0, 0) + matrix4x4_[1][2] * matrix(0, 1) + matrix4x4_[2][2] * matrix(0, 2) +
295             matrix4x4_[3][2] * matrix(0, 3),
296         matrix4x4_[0][2] * matrix(1, 0) + matrix4x4_[1][2] * matrix(1, 1) + matrix4x4_[2][2] * matrix(1, 2) +
297             matrix4x4_[3][2] * matrix(1, 3),
298         matrix4x4_[0][2] * matrix(2, 0) + matrix4x4_[1][2] * matrix(2, 1) + matrix4x4_[2][2] * matrix(2, 2) +
299             matrix4x4_[3][2] * matrix(2, 3),
300         matrix4x4_[0][2] * matrix(3, 0) + matrix4x4_[1][2] * matrix(3, 1) + matrix4x4_[2][2] * matrix(3, 2) +
301             matrix4x4_[3][2] * matrix(3, 3),
302         matrix4x4_[0][3] * matrix(0, 0) + matrix4x4_[1][3] * matrix(0, 1) + matrix4x4_[2][3] * matrix(0, 2) +
303             matrix4x4_[3][3] * matrix(0, 3),
304         matrix4x4_[0][3] * matrix(1, 0) + matrix4x4_[1][3] * matrix(1, 1) + matrix4x4_[2][3] * matrix(1, 2) +
305             matrix4x4_[3][3] * matrix(1, 3),
306         matrix4x4_[0][3] * matrix(2, 0) + matrix4x4_[1][3] * matrix(2, 1) + matrix4x4_[2][3] * matrix(2, 2) +
307             matrix4x4_[3][3] * matrix(2, 3),
308         matrix4x4_[0][3] * matrix(3, 0) + matrix4x4_[1][3] * matrix(3, 1) + matrix4x4_[2][3] * matrix(3, 2) +
309             matrix4x4_[3][3] * matrix(3, 3));
310 }
311 
operator *(const Matrix4N & matrix) const312 Matrix4N Matrix4::operator*(const Matrix4N& matrix) const
313 {
314     int32_t columns = matrix.GetColNum();
315     Matrix4N matrix4n(columns);
316     for (auto i = 0; i < DIMENSION; i++) {
317         for (auto j = 0; j < columns; j++) {
318             double value = 0.0;
319             for (auto k = 0; k < DIMENSION; k++) {
320                 value += matrix4x4_[i][k] * matrix[k][j];
321             }
322             matrix4n[i][j] = value;
323         }
324     }
325     return matrix4n;
326 }
327 
operator *(const Point & point)328 Point Matrix4::operator*(const Point& point)
329 {
330     double x = point.GetX();
331     double y = point.GetY();
332     return Point(matrix4x4_[0][0] * x + matrix4x4_[1][0] * y + matrix4x4_[3][0],
333         matrix4x4_[0][1] * x + matrix4x4_[1][1] * y + matrix4x4_[3][1]);
334 }
335 
operator =(const Matrix4 & matrix)336 Matrix4& Matrix4::operator=(const Matrix4& matrix)
337 {
338     if (this == &matrix) {
339         return *this;
340     }
341     std::copy_n(&matrix.matrix4x4_[0][0], MATRIX_LENGTH, &matrix4x4_[0][0]);
342     return *this;
343 }
344 
operator [](int32_t index) const345 double Matrix4::operator[](int32_t index) const
346 {
347     if (index < 0 || index >= MATRIX_LENGTH) {
348         return 0.0f;
349     }
350     int32_t row = index / DIMENSION;
351     int32_t col = index % DIMENSION;
352     return matrix4x4_[row][col];
353 }
354 
operator ()(int32_t row,int32_t col) const355 double Matrix4::operator()(int32_t row, int32_t col) const
356 {
357     // Caller guarantee row and col in range of [0, 3].
358     return matrix4x4_[row][col];
359 }
360 
Determinant() const361 double Matrix4::Determinant() const
362 {
363     if (this->IsIdentityMatrix()) {
364         return 1.0;
365     }
366 
367     double m00 = matrix4x4_[0][0];
368     double m01 = matrix4x4_[0][1];
369     double m02 = matrix4x4_[0][2];
370     double m03 = matrix4x4_[0][3];
371     double m10 = matrix4x4_[1][0];
372     double m11 = matrix4x4_[1][1];
373     double m12 = matrix4x4_[1][2];
374     double m13 = matrix4x4_[1][3];
375     double m20 = matrix4x4_[2][0];
376     double m21 = matrix4x4_[2][1];
377     double m22 = matrix4x4_[2][2];
378     double m23 = matrix4x4_[2][3];
379     double m30 = matrix4x4_[3][0];
380     double m31 = matrix4x4_[3][1];
381     double m32 = matrix4x4_[3][2];
382     double m33 = matrix4x4_[3][3];
383 
384     double b00 = m00 * m11 - m01 * m10;
385     double b01 = m00 * m12 - m02 * m10;
386     double b02 = m00 * m13 - m03 * m10;
387     double b03 = m01 * m12 - m02 * m11;
388     double b04 = m01 * m13 - m03 * m11;
389     double b05 = m02 * m13 - m03 * m12;
390     double b06 = m20 * m31 - m21 * m30;
391     double b07 = m20 * m32 - m22 * m30;
392     double b08 = m20 * m33 - m23 * m30;
393     double b09 = m21 * m32 - m22 * m31;
394     double b10 = m21 * m33 - m23 * m31;
395     double b11 = m22 * m33 - m23 * m32;
396 
397     return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
398 }
399 
Transpose()400 void Matrix4::Transpose()
401 {
402     std::swap(matrix4x4_[0][1], matrix4x4_[1][0]);
403     std::swap(matrix4x4_[0][2], matrix4x4_[2][0]);
404     std::swap(matrix4x4_[0][3], matrix4x4_[3][0]);
405     std::swap(matrix4x4_[1][2], matrix4x4_[2][1]);
406     std::swap(matrix4x4_[1][3], matrix4x4_[3][1]);
407     std::swap(matrix4x4_[2][3], matrix4x4_[3][2]);
408 }
409 
MapScalars(const double src[DIMENSION],double dst[DIMENSION]) const410 void Matrix4::MapScalars(const double src[DIMENSION], double dst[DIMENSION]) const
411 {
412     double storage[DIMENSION];
413 
414     double* result = (src == dst) ? storage : dst;
415 
416     for (int i = 0; i < DIMENSION; i++) {
417         double value = 0;
418         for (int j = 0; j < DIMENSION; j++) {
419             value += matrix4x4_[j][i] * src[j];
420         }
421         result[i] = value;
422     }
423 
424     if (storage == result) {
425         std::copy_n(result, DIMENSION, dst);
426     }
427 }
428 
ToString() const429 std::string Matrix4::ToString() const
430 {
431     std::string out;
432     for (auto& i : matrix4x4_) {
433         for (double j : i) {
434             out += std::to_string(j);
435             out += ",";
436         }
437         out += "\n";
438     }
439     return out;
440 }
441 
Matrix4N(int32_t columns)442 Matrix4N::Matrix4N(int32_t columns) : columns_(columns)
443 {
444     matrix4n_.resize(DIMENSION, std::vector<double>(columns_, 0));
445 }
446 
SetEntry(int32_t row,int32_t col,double value)447 bool Matrix4N::SetEntry(int32_t row, int32_t col, double value)
448 {
449     if (row < 0 || row >= DIMENSION || col < 0 || col >= columns_) {
450         return false;
451     }
452     matrix4n_[row][col] = value;
453     return true;
454 }
455 
operator *(const MatrixN4 & matrix) const456 Matrix4 Matrix4N::operator*(const MatrixN4& matrix) const
457 {
458     auto matrix4 = Matrix4::CreateIdentity();
459     if (columns_ != matrix.GetRowNum()) {
460         return matrix4;
461     }
462     for (auto i = 0; i < DIMENSION; i++) {
463         for (auto j = 0; j < DIMENSION; j++) {
464             double value = 0.0;
465             for (auto k = 0; k < columns_; k++) {
466                 value += matrix4n_[i][k] * matrix[k][j];
467             }
468             matrix4.SetEntry(i, j, value);
469         }
470     }
471     return matrix4;
472 }
473 
Transpose() const474 MatrixN4 Matrix4N::Transpose() const
475 {
476     MatrixN4 matrix { columns_ };
477     for (auto i = 0; i < DIMENSION; i++) {
478         for (auto j = 0; j < columns_; j++) {
479             matrix[j][i] = matrix4n_[i][j];
480         }
481     }
482     return matrix;
483 }
484 
MapScalars(const std::vector<double> & src) const485 std::vector<double> Matrix4N::MapScalars(const std::vector<double>& src) const
486 {
487     std::vector<double> value(DIMENSION, 0);
488     if (static_cast<int32_t>(src.size()) != columns_) {
489         return value;
490     }
491     for (int32_t i = 0; i < DIMENSION; i++) {
492         double item = 0.0;
493         for (int32_t j = 0; j < columns_; j++) {
494             item = item + matrix4n_[i][j] * src[j];
495         }
496         value[i] = item;
497     }
498     return value;
499 }
500 
MapScalars(const std::vector<double> & src,std::vector<double> & result) const501 bool Matrix4N::MapScalars(const std::vector<double>& src, std::vector<double>& result) const
502 {
503     if (static_cast<int32_t>(src.size()) != columns_) {
504         return false;
505     }
506     result.resize(DIMENSION, 0);
507     for (int32_t i = 0; i < DIMENSION; i++) {
508         double item = 0.0;
509         for (int32_t j = 0; j < columns_; j++) {
510             item = item + matrix4n_[i][j] * src[j];
511         }
512         result[i] = item;
513     }
514     return true;
515 }
516 
MatrixN4(int32_t rows)517 MatrixN4::MatrixN4(int32_t rows) : rows_(rows)
518 {
519     matrixn4_.resize(rows, std::vector<double>(DIMENSION, 0));
520 }
521 
SetEntry(int32_t row,int32_t col,double value)522 bool MatrixN4::SetEntry(int32_t row, int32_t col, double value)
523 {
524     if (row < 0 || row >= rows_ || col < 0 || col >= DIMENSION) {
525         return false;
526     }
527     matrixn4_[row][col] = value;
528     return true;
529 }
530 
Transpose() const531 Matrix4N MatrixN4::Transpose() const
532 {
533     Matrix4N matrix { rows_ };
534     for (auto i = 0; i < DIMENSION; i++) {
535         for (auto j = 0; j < rows_; j++) {
536             matrix[i][j] = matrixn4_[j][i];
537         }
538     }
539     return matrix;
540 }
541 
MapScalars(const std::vector<double> & src) const542 std::vector<double> MatrixN4::MapScalars(const std::vector<double>& src) const
543 {
544     std::vector<double> value(rows_, 0);
545     if (static_cast<int32_t>(src.size()) != DIMENSION) {
546         return value;
547     }
548     for (int32_t i = 0; i < rows_; i++) {
549         double item = 0.0;
550         for (int32_t j = 0; j < DIMENSION; j++) {
551             item = item + matrixn4_[i][j] * src[j];
552         }
553         value[i] = item;
554     }
555     return value;
556 }
557 } // namespace OHOS::Ace
558