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