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