• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "matrix4.h"
17 #include <algorithm>
18 #include <cmath>
19 #include "utils.h"
20 
21 namespace OHOS::uitest {
22 namespace {
23 constexpr int32_t MATRIX_LENGTH = Matrix4::DIMENSION * Matrix4::DIMENSION;
24 constexpr double ANGLE_UNIT = 0.017453f; // PI / 180
IsEqual(const double & left,const double & right)25 inline bool IsEqual(const double& left, const double& right)
26 {
27     return NearEqual(left, right);
28 }
29 } // namespace
30 
CreateIdentity()31 Matrix4 Matrix4::CreateIdentity()
32 {
33     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);
34 }
35 
CreateTranslate(double x,double y,double z)36 Matrix4 Matrix4::CreateTranslate(double x, double y, double z)
37 {
38     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);
39 }
40 
CreateScale(double x,double y,double z)41 Matrix4 Matrix4::CreateScale(double x, double y, double z)
42 {
43     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);
44 }
45 
CreateMatrix2D(double m00,double m10,double m01,double m11,double m03,double m13)46 Matrix4 Matrix4::CreateMatrix2D(double m00, double m10, double m01, double m11, double m03, double m13)
47 {
48     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);
49 }
50 
CreateSkew(double x,double y)51 Matrix4 Matrix4::CreateSkew(double x, double y)
52 {
53     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,
54         1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
55 }
56 
CreatePerspective(double distance)57 Matrix4 Matrix4::CreatePerspective(double distance)
58 {
59     auto result = CreateIdentity();
60     if (GreatNotEqual(distance, 0.0f)) {
61         result.matrix4x4_[TWO][THREE] = -1.0f / distance;
62     }
63     return result;
64 }
65 
Invert(const Matrix4 & matrix)66 Matrix4 Matrix4::Invert(const Matrix4& matrix)
67 {
68     Matrix4 inverted = CreateInvert(matrix);
69     double determinant = matrix(ZERO, ZERO) * inverted(ZERO, ZERO) + matrix(ZERO, ONE) * inverted(ONE, ZERO) +
70     matrix(ZERO, TWO) * inverted(TWO, ZERO) + matrix(ZERO, THREE) * inverted(THREE, ZERO);
71     if (!NearZero(determinant)) {
72         inverted = inverted * (1.0f / determinant);
73     } else {
74         inverted = CreateIdentity();
75     }
76     return inverted;
77 }
78 
Matrix4()79 Matrix4::Matrix4()
80     : 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)
81 {}
82 
Matrix4(const Matrix4 & matrix)83 Matrix4::Matrix4(const Matrix4& matrix)
84 {
85     std::copy_n(&matrix.matrix4x4_[ZERO][ZERO], MATRIX_LENGTH, &matrix4x4_[ZERO][ZERO]);
86 }
87 
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)88 Matrix4::Matrix4(double m00, double m01, double m02, double m03, double m10, double m11, double m12, double m13,
89     double m20, double m21, double m22, double m23, double m30, double m31, double m32, double m33)
90 {
91     matrix4x4_[ZERO][ZERO] = m00;
92     matrix4x4_[ONE][ZERO] = m01;
93     matrix4x4_[TWO][ZERO] = m02;
94     matrix4x4_[THREE][ZERO] = m03;
95     matrix4x4_[ZERO][ONE] = m10;
96     matrix4x4_[ONE][ONE] = m11;
97     matrix4x4_[TWO][ONE] = m12;
98     matrix4x4_[THREE][ONE] = m13;
99     matrix4x4_[ZERO][TWO] = m20;
100     matrix4x4_[ONE][TWO] = m21;
101     matrix4x4_[TWO][TWO] = m22;
102     matrix4x4_[THREE][TWO] = m23;
103     matrix4x4_[ZERO][THREE] = m30;
104     matrix4x4_[ONE][THREE] = m31;
105     matrix4x4_[TWO][THREE] = m32;
106     matrix4x4_[THREE][THREE] = m33;
107 }
108 
SetEntry(int32_t row,int32_t col,double value)109 void Matrix4::SetEntry(int32_t row, int32_t col, double value)
110 {
111     if ((row < ZERO || row >= DIMENSION) || (col < ZERO || col >= DIMENSION)) {
112         return;
113     }
114     matrix4x4_[row][col] = value;
115 }
116 
IsIdentityMatrix() const117 bool Matrix4::IsIdentityMatrix() const
118 {
119     return *this == CreateIdentity();
120 }
121 
Count()122 int32_t Matrix4::Count()
123 {
124     return MATRIX_LENGTH;
125 }
126 
CreateInvert(const Matrix4 & matrix)127 Matrix4 Matrix4::CreateInvert(const Matrix4& matrix)
128 {
129     return Matrix4(
130         matrix(ONE, ONE) * matrix(TWO, TWO) * matrix(THREE, THREE) - matrix(ONE, ONE) * matrix(TWO, THREE) *
131         matrix(THREE, TWO) - matrix(TWO, ONE) * matrix(ONE, TWO) * matrix(THREE, THREE) + matrix(TWO, ONE) *
132         matrix(ONE, THREE) * matrix(THREE, TWO) + matrix(THREE, ONE) * matrix(ONE, TWO) * matrix(TWO, THREE) -
133         matrix(THREE, ONE) * matrix(ONE, THREE) * matrix(TWO, TWO),
134         -matrix(ONE, ZERO) * matrix(TWO, TWO) * matrix(THREE, THREE) + matrix(ONE, ZERO) * matrix(TWO, THREE) *
135         matrix(THREE, TWO) + matrix(TWO, ZERO) * matrix(ONE, TWO) * matrix(THREE, THREE) - matrix(TWO, ZERO) *
136         matrix(ONE, THREE) * matrix(THREE, TWO) - matrix(THREE, ZERO) * matrix(ONE, TWO) * matrix(TWO, THREE) +
137         matrix(THREE, ZERO) * matrix(ONE, THREE) * matrix(TWO, TWO),
138         matrix(ONE, ZERO) * matrix(TWO, ONE) * matrix(THREE, THREE) - matrix(ONE, ZERO) * matrix(TWO, THREE) *
139         matrix(THREE, ONE) - matrix(TWO, ZERO) * matrix(ONE, ONE) * matrix(THREE, THREE) + matrix(TWO, ZERO) *
140         matrix(ONE, THREE) * matrix(THREE, ONE) + matrix(THREE, ZERO) * matrix(ONE, ONE) * matrix(TWO, THREE) -
141         matrix(THREE, ZERO) * matrix(ONE, THREE) * matrix(TWO, ONE),
142         -matrix(ONE, ZERO) * matrix(TWO, ONE) * matrix(THREE, TWO) + matrix(ONE, ZERO) * matrix(TWO, TWO) *
143         matrix(THREE, ONE) + matrix(TWO, ZERO) * matrix(ONE, ONE) * matrix(THREE, TWO) - matrix(TWO, ZERO) *
144         matrix(ONE, TWO) * matrix(THREE, ONE) - matrix(THREE, ZERO) * matrix(ONE, ONE) * matrix(TWO, TWO) +
145         matrix(THREE, ZERO) * matrix(ONE, TWO) * matrix(TWO, ONE),
146         -matrix(ZERO, ONE) * matrix(TWO, TWO) * matrix(THREE, THREE) + matrix(ZERO, ONE) * matrix(TWO, THREE) *
147         matrix(THREE, TWO) + matrix(TWO, ONE) * matrix(ZERO, TWO) * matrix(THREE, THREE) - matrix(TWO, ONE) *
148         matrix(ZERO, THREE) * matrix(THREE, TWO) - matrix(THREE, ONE) * matrix(ZERO, TWO) * matrix(TWO, THREE) +
149         matrix(THREE, ONE) * matrix(ZERO, THREE) * matrix(TWO, TWO),
150         matrix(ZERO, ZERO) * matrix(TWO, TWO) * matrix(THREE, THREE) - matrix(ZERO, ZERO) * matrix(TWO, THREE) *
151         matrix(THREE, TWO) - matrix(TWO, ZERO) * matrix(ZERO, TWO) * matrix(THREE, THREE) + matrix(TWO, ZERO) *
152         matrix(ZERO, THREE) * matrix(THREE, TWO) + matrix(THREE, ZERO) * matrix(ZERO, TWO) * matrix(TWO, THREE) -
153         matrix(THREE, ZERO) * matrix(ZERO, THREE) * matrix(TWO, TWO),
154         -matrix(ZERO, ZERO) * matrix(TWO, ONE) * matrix(THREE, THREE) + matrix(ZERO, ZERO) * matrix(TWO, THREE) *
155         matrix(THREE, ONE) + matrix(TWO, ZERO) * matrix(ZERO, ONE) * matrix(THREE, THREE) - matrix(TWO, ZERO) *
156         matrix(ZERO, THREE) * matrix(THREE, ONE) - matrix(THREE, ZERO) * matrix(ZERO, ONE) * matrix(TWO, THREE) +
157         matrix(THREE, ZERO) * matrix(ZERO, THREE) * matrix(TWO, ONE),
158         matrix(ZERO, ZERO) * matrix(TWO, ONE) * matrix(THREE, TWO) - matrix(ZERO, ZERO) * matrix(TWO, TWO) *
159         matrix(THREE, ONE) - matrix(TWO, ZERO) * matrix(ZERO, ONE) * matrix(THREE, TWO) + matrix(TWO, ZERO) *
160         matrix(ZERO, TWO) * matrix(THREE, ONE) + matrix(THREE, ZERO) * matrix(ZERO, ONE) * matrix(TWO, TWO) -
161         matrix(THREE, ZERO) * matrix(ZERO, TWO) * matrix(TWO, ONE),
162         matrix(ZERO, ONE) * matrix(ONE, TWO) * matrix(THREE, THREE) - matrix(ZERO, ONE) * matrix(ONE, THREE) *
163         matrix(THREE, TWO) - matrix(ONE, ONE) * matrix(ZERO, TWO) * matrix(THREE, THREE) + matrix(ONE, ONE) *
164         matrix(ZERO, THREE) * matrix(THREE, TWO) + matrix(THREE, ONE) * matrix(ZERO, TWO) * matrix(ONE, THREE) -
165         matrix(THREE, ONE) * matrix(ZERO, THREE) * matrix(ONE, TWO),
166         -matrix(ZERO, ZERO) * matrix(ONE, TWO) * matrix(THREE, THREE) + matrix(ZERO, ZERO) * matrix(ONE, THREE) *
167         matrix(THREE, TWO) +  matrix(ONE, ZERO) * matrix(ZERO, TWO) * matrix(THREE, THREE) - matrix(ONE, ZERO) *
168         matrix(ZERO, THREE) * matrix(THREE, TWO) - matrix(THREE, ZERO) * matrix(ZERO, TWO) * matrix(ONE, THREE) +
169         matrix(THREE, ZERO) * matrix(ZERO, THREE) * matrix(ONE, TWO),
170         matrix(ZERO, ZERO) * matrix(ONE, ONE) * matrix(THREE, THREE) - matrix(ZERO, ZERO) * matrix(ONE, THREE) *
171         matrix(THREE, ONE) - matrix(ONE, ZERO) * matrix(ZERO, ONE) * matrix(THREE, THREE) + matrix(ONE, ZERO) *
172         matrix(ZERO, THREE) * matrix(THREE, ONE) + matrix(THREE, ZERO) * matrix(ZERO, ONE) * matrix(ONE, THREE) -
173         matrix(THREE, ZERO) * matrix(ZERO, THREE) * matrix(ONE, ONE),
174         -matrix(ZERO, ZERO) * matrix(ONE, ONE) * matrix(THREE, TWO) + matrix(ZERO, ZERO) * matrix(ONE, TWO) *
175         matrix(THREE, ONE) + matrix(ONE, ZERO) * matrix(ZERO, ONE) * matrix(THREE, TWO) - matrix(ONE, ZERO) *
176         matrix(ZERO, TWO) * matrix(THREE, ONE) - matrix(THREE, ZERO) * matrix(ZERO, ONE) * matrix(ONE, TWO) +
177         matrix(THREE, ZERO) * matrix(ZERO, TWO) * matrix(ONE, ONE),
178         -matrix(ZERO, ONE) * matrix(ONE, TWO) * matrix(TWO, THREE) + matrix(ZERO, ONE) * matrix(ONE, THREE) *
179         matrix(TWO, TWO) + matrix(ONE, ONE) * matrix(ZERO, TWO) * matrix(TWO, THREE) - matrix(ONE, ONE) *
180         matrix(ZERO, THREE) * matrix(TWO, TWO) - matrix(TWO, ONE) * matrix(ZERO, TWO) * matrix(ONE, THREE)
181         + matrix(TWO, ONE) * matrix(ZERO, THREE) * matrix(ONE, TWO),
182         matrix(ZERO, ZERO) * matrix(ONE, TWO) * matrix(TWO, THREE) - matrix(ZERO, ZERO) * matrix(ONE, THREE) *
183         matrix(TWO, TWO) - matrix(ONE, ZERO) * matrix(ZERO, TWO) * matrix(TWO, THREE) + matrix(ONE, ZERO) *
184         matrix(ZERO, THREE) * matrix(TWO, TWO) + matrix(TWO, ZERO) * matrix(ZERO, TWO) * matrix(ONE, THREE) -
185         matrix(TWO, ZERO) * matrix(ZERO, THREE) * matrix(ONE, TWO),
186         -matrix(ZERO, ZERO) * matrix(ONE, ONE) * matrix(TWO, THREE) + matrix(ZERO, ZERO) * matrix(ONE, THREE) *
187         matrix(TWO, ONE) + matrix(ONE, ZERO) * matrix(ZERO, ONE) * matrix(TWO, THREE) - matrix(ONE, ZERO) *
188         matrix(ZERO, THREE) * matrix(TWO, ONE) - matrix(TWO, ZERO) * matrix(ZERO, ONE) * matrix(ONE, THREE) +
189         matrix(TWO, ZERO) * matrix(ZERO, THREE) * matrix(ONE, ONE),
190         matrix(ZERO, ZERO) * matrix(ONE, ONE) * matrix(TWO, TWO) - matrix(ZERO, ZERO) * matrix(ONE, TWO) *
191         matrix(TWO, ONE) - matrix(ONE, ZERO) * matrix(ZERO, ONE) * matrix(TWO, TWO) + matrix(ONE, ZERO) *
192         matrix(ZERO, TWO) * matrix(TWO, ONE) + matrix(TWO, ZERO) * matrix(ZERO, ONE) * matrix(ONE, TWO) -
193         matrix(TWO, ZERO) * matrix(ZERO, TWO) * matrix(ONE, ONE));
194 }
195 
operator ==(const Matrix4 & matrix) const196 bool Matrix4::operator==(const Matrix4& matrix) const
197 {
198     return std::equal(&matrix4x4_[ZERO][ZERO], &matrix4x4_[ZERO][ZERO] + MATRIX_LENGTH,
199                       &matrix.matrix4x4_[ZERO][ZERO], IsEqual);
200 }
201 
operator *(double num)202 Matrix4 Matrix4::operator*(double num)
203 {
204     Matrix4 ret(*this);
205     auto function = [num](double& v) { v *= num; };
206     auto it = &ret.matrix4x4_[ZERO][ZERO];
207     for (int32_t i = ZERO; i < MATRIX_LENGTH; ++it, ++i) {
208         function(*it);
209     }
210     return ret;
211 }
212 
operator *(const Matrix4 & matrix)213 Matrix4 Matrix4::operator*(const Matrix4& matrix)
214 {
215     return Matrix4(
216         matrix4x4_[ZERO][ZERO] * matrix(ZERO, ZERO) + matrix4x4_[ONE][ZERO] * matrix(ZERO, ONE) +
217         matrix4x4_[TWO][ZERO] * matrix(ZERO, TWO) + matrix4x4_[THREE][ZERO] * matrix(ZERO, THREE),
218         matrix4x4_[ZERO][ZERO] * matrix(ONE, ZERO) + matrix4x4_[ONE][ZERO] * matrix(ONE, ONE) +
219         matrix4x4_[TWO][ZERO] * matrix(ONE, TWO) + matrix4x4_[THREE][ZERO] * matrix(ONE, THREE),
220         matrix4x4_[ZERO][ZERO] * matrix(TWO, ZERO) + matrix4x4_[ONE][ZERO] * matrix(TWO, ONE) +
221         matrix4x4_[TWO][ZERO] * matrix(TWO, TWO) + matrix4x4_[THREE][ZERO] * matrix(TWO, THREE),
222         matrix4x4_[ZERO][ZERO] * matrix(THREE, ZERO) + matrix4x4_[ONE][ZERO] * matrix(THREE, ONE) +
223         matrix4x4_[TWO][ZERO] * matrix(THREE, TWO) + matrix4x4_[THREE][ZERO] * matrix(THREE, THREE),
224         matrix4x4_[ZERO][ONE] * matrix(ZERO, ZERO) + matrix4x4_[ONE][ONE] * matrix(ZERO, ONE) +
225         matrix4x4_[TWO][ONE] * matrix(ZERO, TWO) + matrix4x4_[THREE][ONE] * matrix(ZERO, THREE),
226         matrix4x4_[ZERO][ONE] * matrix(ONE, ZERO) + matrix4x4_[ONE][ONE] * matrix(ONE, ONE) +
227         matrix4x4_[TWO][ONE] * matrix(ONE, TWO) + matrix4x4_[THREE][ONE] * matrix(ONE, THREE),
228         matrix4x4_[ZERO][ONE] * matrix(TWO, ZERO) + matrix4x4_[ONE][ONE] * matrix(TWO, ONE) +
229         matrix4x4_[TWO][ONE] * matrix(TWO, TWO) + matrix4x4_[THREE][ONE] * matrix(TWO, THREE),
230         matrix4x4_[ZERO][ONE] * matrix(THREE, ZERO) + matrix4x4_[ONE][ONE] * matrix(THREE, ONE) +
231         matrix4x4_[TWO][ONE] * matrix(THREE, TWO) + matrix4x4_[THREE][ONE] * matrix(THREE, THREE),
232         matrix4x4_[ZERO][TWO] * matrix(ZERO, ZERO) + matrix4x4_[ONE][TWO] * matrix(ZERO, ONE) +
233         matrix4x4_[TWO][TWO] * matrix(ZERO, TWO) + matrix4x4_[THREE][TWO] * matrix(ZERO, THREE),
234         matrix4x4_[ZERO][TWO] * matrix(ONE, ZERO) + matrix4x4_[ONE][TWO] * matrix(ONE, ONE) +
235         matrix4x4_[TWO][TWO] * matrix(ONE, TWO) + matrix4x4_[THREE][TWO] * matrix(ONE, THREE),
236         matrix4x4_[ZERO][TWO] * matrix(TWO, ZERO) + matrix4x4_[ONE][TWO] * matrix(TWO, ONE) +
237         matrix4x4_[TWO][TWO] * matrix(TWO, TWO) + matrix4x4_[THREE][TWO] * matrix(TWO, THREE),
238         matrix4x4_[ZERO][TWO] * matrix(THREE, ZERO) + matrix4x4_[ONE][TWO] * matrix(THREE, ONE) +
239         matrix4x4_[TWO][TWO] * matrix(THREE, TWO) + matrix4x4_[THREE][TWO] * matrix(THREE, THREE),
240         matrix4x4_[ZERO][THREE] * matrix(ZERO, ZERO) + matrix4x4_[ONE][THREE] * matrix(ZERO, ONE) +
241         matrix4x4_[TWO][THREE] * matrix(ZERO, TWO) + matrix4x4_[THREE][THREE] * matrix(ZERO, THREE),
242         matrix4x4_[ZERO][THREE] * matrix(ONE, ZERO) + matrix4x4_[ONE][THREE] * matrix(ONE, ONE) +
243         matrix4x4_[TWO][THREE] * matrix(ONE, TWO) + matrix4x4_[THREE][THREE] * matrix(ONE, THREE),
244         matrix4x4_[ZERO][THREE] * matrix(TWO, ZERO) + matrix4x4_[ONE][THREE] * matrix(TWO, ONE) +
245         matrix4x4_[TWO][THREE] * matrix(TWO, TWO) + matrix4x4_[THREE][THREE] * matrix(TWO, THREE),
246         matrix4x4_[ZERO][THREE] * matrix(THREE, ZERO) + matrix4x4_[ONE][THREE] * matrix(THREE, ONE) +
247         matrix4x4_[TWO][THREE] * matrix(THREE, TWO) + matrix4x4_[THREE][THREE] * matrix(THREE, THREE));
248 }
249 
operator *(const Matrix4N & matrix) const250 Matrix4N Matrix4::operator*(const Matrix4N& matrix) const
251 {
252     int32_t columns = matrix.GetColNum();
253     Matrix4N matrix4n { columns };
254     for (auto i = 0; i < DIMENSION; i++) {
255         for (auto j = 0; j < columns; j++) {
256             double value = 0.0;
257             for (auto k = 0; k < DIMENSION; k++) {
258                 value += matrix4x4_[i][k] * matrix[k][j];
259             }
260             matrix4n[i][j] = value;
261         }
262     }
263     return matrix4n;
264 }
265 
operator *(const Point & point)266 Point Matrix4::operator*(const Point& point)
267 {
268     double x = point.GetX();
269     double y = point.GetY();
270     return Point(matrix4x4_[ZERO][ZERO] * x + matrix4x4_[ONE][ZERO] * y + matrix4x4_[THREE][ZERO],
271         matrix4x4_[ZERO][ONE] * x + matrix4x4_[ONE][ONE] * y + matrix4x4_[THREE][ONE]);
272 }
273 
operator =(const Matrix4 & matrix)274 Matrix4& Matrix4::operator=(const Matrix4& matrix)
275 {
276     if (this == &matrix) {
277         return *this;
278     }
279     std::copy_n(&matrix.matrix4x4_[ZERO][ZERO], MATRIX_LENGTH, &matrix4x4_[ZERO][ZERO]);
280     return *this;
281 }
282 
operator [](int32_t index) const283 double Matrix4::operator[](int32_t index) const
284 {
285     if (index < ZERO || index >= MATRIX_LENGTH) {
286         return 0.0f;
287     }
288     int32_t row = index / DIMENSION;
289     int32_t col = index % DIMENSION;
290     return matrix4x4_[row][col];
291 }
292 
operator ()(int32_t row,int32_t col) const293 double Matrix4::operator()(int32_t row, int32_t col) const
294 {
295     // Caller guarantee row and col in range of [0, THREE].
296     return matrix4x4_[row][col];
297 }
298 
Determinant() const299 double Matrix4::Determinant() const
300 {
301     if (this->IsIdentityMatrix()) {
302         return 1.0;
303     }
304 
305     double m00 = matrix4x4_[ZERO][ZERO];
306     double m01 = matrix4x4_[ZERO][ONE];
307     double m02 = matrix4x4_[ZERO][TWO];
308     double m03 = matrix4x4_[ZERO][THREE];
309     double m10 = matrix4x4_[ONE][ZERO];
310     double m11 = matrix4x4_[ONE][ONE];
311     double m12 = matrix4x4_[ONE][TWO];
312     double m13 = matrix4x4_[ONE][THREE];
313     double m20 = matrix4x4_[TWO][ZERO];
314     double m21 = matrix4x4_[TWO][ONE];
315     double m22 = matrix4x4_[TWO][TWO];
316     double m23 = matrix4x4_[TWO][THREE];
317     double m30 = matrix4x4_[THREE][ZERO];
318     double m31 = matrix4x4_[THREE][ONE];
319     double m32 = matrix4x4_[THREE][TWO];
320     double m33 = matrix4x4_[THREE][THREE];
321 
322     double b00 = m00 * m11 - m01 * m10;
323     double b01 = m00 * m12 - m02 * m10;
324     double b02 = m00 * m13 - m03 * m10;
325     double b03 = m01 * m12 - m02 * m11;
326     double b04 = m01 * m13 - m03 * m11;
327     double b05 = m02 * m13 - m03 * m12;
328     double b06 = m20 * m31 - m21 * m30;
329     double b07 = m20 * m32 - m22 * m30;
330     double b08 = m20 * m33 - m23 * m30;
331     double b09 = m21 * m32 - m22 * m31;
332     double b10 = m21 * m33 - m23 * m31;
333     double b11 = m22 * m33 - m23 * m32;
334 
335     return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
336 }
337 
Transpose()338 void Matrix4::Transpose()
339 {
340     std::swap(matrix4x4_[ZERO][ONE], matrix4x4_[ONE][ZERO]);
341     std::swap(matrix4x4_[ZERO][TWO], matrix4x4_[TWO][ZERO]);
342     std::swap(matrix4x4_[ZERO][THREE], matrix4x4_[THREE][ZERO]);
343     std::swap(matrix4x4_[ONE][TWO], matrix4x4_[TWO][ONE]);
344     std::swap(matrix4x4_[ONE][THREE], matrix4x4_[THREE][ONE]);
345     std::swap(matrix4x4_[TWO][THREE], matrix4x4_[THREE][TWO]);
346 }
347 
ScaleMapping(const double src[DIMENSION],double dst[DIMENSION]) const348 void Matrix4::ScaleMapping(const double src[DIMENSION], double dst[DIMENSION]) const
349 {
350     double storage[DIMENSION];
351 
352     double* result = (src == dst) ? storage : dst;
353 
354     for (int i = 0; i < DIMENSION; i++) {
355         double value = 0;
356         for (int j = 0; j < DIMENSION; j++) {
357             value += matrix4x4_[j][i] * src[j];
358         }
359         result[i] = value;
360     }
361 
362     if (storage == result) {
363         std::copy_n(result, DIMENSION, dst);
364     }
365 }
366 
ToString() const367 std::string Matrix4::ToString() const
368 {
369     std::string out;
370     for (const auto& i : matrix4x4_) {
371         for (double j : i) {
372             out += std::to_string(j);
373             out += ",";
374         }
375         out += "\n";
376     }
377     return out;
378 }
379 
Matrix4N(int32_t columns)380 Matrix4N::Matrix4N(int32_t columns) : columns_(columns)
381 {
382     matrix4n_.resize(DIMENSION, std::vector<double>(columns_, 0));
383 }
384 
SetEntry(int32_t row,int32_t col,double value)385 bool Matrix4N::SetEntry(int32_t row, int32_t col, double value)
386 {
387     if (row >= DIMENSION || col >= columns_) {
388         return false;
389     }
390     matrix4n_[row][col] = value;
391     return true;
392 }
393 
operator *(const MatrixN4 & matrix) const394 Matrix4 Matrix4N::operator*(const MatrixN4& matrix) const
395 {
396     auto matrix4 = Matrix4::CreateIdentity();
397     if (columns_ != matrix.GetRowNum()) {
398         return matrix4;
399     }
400     for (int i = 0; i < DIMENSION; i++) {
401         for (int j = 0; j < DIMENSION; j++) {
402             double value = 0.0;
403             for (int k = 0; k < columns_; k++) {
404                 value += matrix4n_[i][k] * matrix[k][j];
405             }
406             matrix4.SetEntry(i, j, value);
407         }
408     }
409     return matrix4;
410 }
411 
Transpose() const412 MatrixN4 Matrix4N::Transpose() const
413 {
414     MatrixN4 matrix { columns_ };
415     for (auto i = 0; i < DIMENSION; i++) {
416         for (auto j = 0; j < columns_; j++) {
417             matrix[j][i] = matrix4n_[i][j];
418         }
419     }
420     return matrix;
421 }
422 
ScaleMapping(const std::vector<double> & src) const423 std::vector<double> Matrix4N::ScaleMapping(const std::vector<double>& src) const
424 {
425     std::vector<double> value { DIMENSION, 0 };
426     if (static_cast<int32_t>(src.size()) != columns_) {
427         return value;
428     }
429     for (int32_t i = 0; i < DIMENSION; i++) {
430         double item = 0.0;
431         for (int32_t j = 0; j < columns_; j++) {
432             item = item + matrix4n_[i][j] * src[j];
433         }
434         value[i] = item;
435     }
436     return value;
437 }
438 
ScaleMapping(const std::vector<double> & src,std::vector<double> & result) const439 bool Matrix4N::ScaleMapping(const std::vector<double>& src, std::vector<double>& result) const
440 {
441     if (static_cast<int32_t>(src.size()) != columns_) {
442         return false;
443     }
444     result.resize(DIMENSION, 0);
445     for (int32_t i = 0; i < DIMENSION; i++) {
446         double item = 0.0;
447         for (int32_t j = 0; j < columns_; j++) {
448             item = item + matrix4n_[i][j] * src[j];
449         }
450         result[i] = item;
451     }
452     return true;
453 }
454 
MatrixN4(int32_t rows)455 MatrixN4::MatrixN4(int32_t rows) : rows_(rows)
456 {
457     matrixn4_.resize(rows, std::vector<double>(DIMENSION, 0));
458 }
459 
SetEntry(int32_t row,int32_t col,double value)460 bool MatrixN4::SetEntry(int32_t row, int32_t col, double value)
461 {
462     if (row >= rows_ || col >= DIMENSION) {
463         return false;
464     }
465     matrixn4_[row][col] = value;
466     return true;
467 }
468 
Transpose() const469 Matrix4N MatrixN4::Transpose() const
470 {
471     Matrix4N matrix { rows_ };
472     for (auto i = 0; i < DIMENSION; i++) {
473         for (auto j = 0; j < rows_; j++) {
474             matrix[i][j] = matrixn4_[j][i];
475         }
476     }
477     return matrix;
478 }
479 
ScaleMapping(const std::vector<double> & src) const480 std::vector<double> MatrixN4::ScaleMapping(const std::vector<double>& src) const
481 {
482     std::vector<double> value { rows_, 0 };
483     if (static_cast<int32_t>(src.size()) != DIMENSION) {
484         return value;
485     }
486     for (int32_t i = 0; i < rows_; i++) {
487         double item = 0.0;
488         for (int32_t j = 0; j < DIMENSION; j++) {
489             item = item + matrixn4_[i][j] * src[j];
490         }
491         value[i] = item;
492     }
493     return value;
494 }
495 } // namespace OHOS::uitest