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