• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #ifndef MMI_MATRIX3_H
17 #define MMI_MATRIX3_H
18 
19 #define USE_MATH_DEFINES
20 
21 #include "mmi_vector2.h"
22 #include "mmi_vector3.h"
23 
24 // column-major order
25 namespace OHOS {
26 namespace MMI {
27 inline constexpr int32_t MATRIX3_SIZE { 9 };
28 template<typename T>
29 class Matrix3 {
30 public:
31     static const Matrix3 ZERO;
32     static const Matrix3 IDENTITY;
33     Matrix3();
34     Matrix3(T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22);
35     Matrix3(std::vector<T> M);
36 
37     Matrix3(const Matrix3& matrix) noexcept = default;
38 
39     explicit Matrix3(const T* v);
40 
41     ~Matrix3();
42     T Trace() const;
43     static int Index(int row, int col);
44     void SetIdentity();
45     void SetZero();
46     bool IsIdentity() const;
47     Matrix3 Inverse() const;
48     Matrix3 Multiply(const Matrix3& other) const;
49 
50     Matrix3 operator+(const Matrix3& other) const;
51     Matrix3 operator-(const Matrix3& other) const;
52     Matrix3 operator-() const;
53     Matrix3 operator*(const Matrix3& other) const;
54     Vector3<T> operator*(const Vector3<T>& other) const;
55     Matrix3 operator*(T scale) const;
56     T* operator[](int col);
57     Matrix3& operator=(const Matrix3& other);
58     Matrix3& operator+=(const Matrix3& other);
59     Matrix3& operator-=(const Matrix3& other);
60     Matrix3& operator*=(const Matrix3& other);
61     Matrix3& operator*=(T scale);
62     bool operator==(const Matrix3& other) const;
63     bool operator!=(const Matrix3& other) const;
64     bool IsNearEqual(const Matrix3& other, T threshold = std::numeric_limits<T>::epsilon()) const;
65     T* GetData();
66     const T* GetConstData() const;
67     T Determinant() const;
68     Matrix3 Transpose() const;
69     Matrix3 Translate(const Vector2<T>& vec) const;
70     Matrix3 Rotate(T angle) const;
71     Matrix3 Rotate(T angle, T pivotx, T pivoty) const;
72     Matrix3 Scale(const Vector2<T>& vec) const;
73     Matrix3 Scale(const Vector2<T>& vec, T pivotx, T pivoty) const;
74     Matrix3 ShearX(T y) const;
75     Matrix3 ShearY(T x) const;
76 
77 protected:
78     T data_[MATRIX3_SIZE] = { 0 };
79 };
80 
81 typedef Matrix3<float> Matrix3f;
82 typedef Matrix3<double> Matrix3d;
83 
84 template<typename T>
85 const Matrix3<T> Matrix3<T>::ZERO(0, 0, 0, 0, 0, 0, 0, 0, 0);
86 
87 template<typename T>
88 const Matrix3<T> Matrix3<T>::IDENTITY(1, 0, 0, 0, 1, 0, 0, 0, 1);
89 
90 template<typename T>
Matrix3()91 Matrix3<T>::Matrix3()
92 {}
93 
94 template<typename T>
Matrix3(T m00,T m01,T m02,T m10,T m11,T m12,T m20,T m21,T m22)95 Matrix3<T>::Matrix3(T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22)
96 {
97     data_[0] = m00;
98     data_[1] = m01;
99     data_[2] = m02;
100 
101     data_[3] = m10;
102     data_[4] = m11;
103     data_[5] = m12;
104 
105     data_[6] = m20;
106     data_[7] = m21;
107     data_[8] = m22;
108 }
109 
110 template<typename T>
Matrix3(std::vector<T> matrix)111 Matrix3<T>::Matrix3(std::vector<T> matrix)
112 {
113     if (matrix.size() != MATRIX3_SIZE) {
114         Matrix3();
115     } else {
116         for (size_t i = 0; i < MATRIX3_SIZE; i++) {
117             data_[i] = matrix[i];
118         }
119     }
120 }
121 
122 template<typename T>
Matrix3(const T * v)123 Matrix3<T>::Matrix3(const T* v)
124 {
125     std::copy_n(v, std::size(data_), data_);
126 }
127 
128 template<typename T>
~Matrix3()129 Matrix3<T>::~Matrix3()
130 {}
131 
132 template<typename T>
Trace()133 T Matrix3<T>::Trace() const
134 {
135     T rTrace = 0.0;
136     rTrace += data_[0];
137     rTrace += data_[4];
138     rTrace += data_[8];
139     return rTrace;
140 }
141 
142 template<typename T>
Index(int row,int col)143 int Matrix3<T>::Index(int row, int col)
144 {
145     return (col * 3) + row;
146 }
147 
148 template<typename T>
SetIdentity()149 void Matrix3<T>::SetIdentity()
150 {
151     *this = IDENTITY;
152 }
153 
154 template<typename T>
SetZero()155 void Matrix3<T>::SetZero()
156 {
157     *this = ZERO;
158 }
159 
160 template<typename T>
IsIdentity()161 bool Matrix3<T>::IsIdentity() const
162 {
163     return (MMI_EQ<T>(data_[0], 1.0)) && (MMI_EQ<T>(data_[1], 0.0)) && (MMI_EQ<T>(data_[2], 0.0)) &&
164            (MMI_EQ<T>(data_[3], 0.0)) && (MMI_EQ<T>(data_[4], 1.0)) && (MMI_EQ<T>(data_[5], 0.0)) &&
165            (MMI_EQ<T>(data_[6], 0.0)) && (MMI_EQ<T>(data_[7], 0.0)) && (MMI_EQ<T>(data_[8], 1.0));
166 }
167 
168 template<typename T>
Inverse()169 Matrix3<T> Matrix3<T>::Inverse() const
170 {
171     T det = Determinant();
172     if (MMI_EQ<T>(det, 0.0)) {
173         return Matrix3<T>(*this);
174     }
175 
176     const T invDet = 1.0f / det;
177     const T* data = data_;
178 
179     T iX = invDet * (data[4] * data[8] - data[5] * data[7]);
180     T iY = invDet * (data[2] * data[7] - data[1] * data[8]);
181     T iZ = invDet * (data[1] * data[5] - data[2] * data[4]);
182     T jX = invDet * (data[5] * data[6] - data[3] * data[8]);
183     T jY = invDet * (data[0] * data[8] - data[2] * data[6]);
184     T jZ = invDet * (data[2] * data[3] - data[0] * data[5]);
185     T kX = invDet * (data[3] * data[7] - data[4] * data[6]);
186     T kY = invDet * (data[1] * data[6] - data[0] * data[7]);
187     T kZ = invDet * (data[0] * data[4] - data[1] * data[3]);
188 
189     return Matrix3<T>(iX, iY, iZ, jX, jY, jZ, kX, kY, kZ);
190 }
191 
192 template<typename T>
Multiply(const Matrix3<T> & other)193 Matrix3<T> Matrix3<T>::Multiply(const Matrix3<T>& other) const
194 {
195     Matrix3<T> rMulti;
196     T* rData = rMulti.data_;
197     const T* oData = other.data_;
198 
199     rData[0] = data_[0] * oData[0] + data_[3] * oData[1] + data_[6] * oData[2];
200     rData[3] = data_[0] * oData[3] + data_[3] * oData[4] + data_[6] * oData[5];
201     rData[6] = data_[0] * oData[6] + data_[3] * oData[7] + data_[6] * oData[8];
202 
203     rData[1] = data_[1] * oData[0] + data_[4] * oData[1] + data_[7] * oData[2];
204     rData[4] = data_[1] * oData[3] + data_[4] * oData[4] + data_[7] * oData[5];
205     rData[7] = data_[1] * oData[6] + data_[4] * oData[7] + data_[7] * oData[8];
206 
207     rData[2] = data_[2] * oData[0] + data_[5] * oData[1] + data_[8] * oData[2];
208     rData[5] = data_[2] * oData[3] + data_[5] * oData[4] + data_[8] * oData[5];
209     rData[8] = data_[2] * oData[6] + data_[5] * oData[7] + data_[8] * oData[8];
210     return rMulti;
211 }
212 
213 template<typename T>
214 Matrix3<T> Matrix3<T>::operator+(const Matrix3<T>& other) const
215 {
216     Matrix3<T> rMat3Add;
217     T* rMat3Data = rMat3Add.data_;
218     const T* oData = other.data_;
219 
220     rMat3Data[0] = data_[0] + oData[0];
221     rMat3Data[1] = data_[1] + oData[1];
222     rMat3Data[2] = data_[2] + oData[2];
223     rMat3Data[3] = data_[3] + oData[3];
224     rMat3Data[4] = data_[4] + oData[4];
225     rMat3Data[5] = data_[5] + oData[5];
226     rMat3Data[6] = data_[6] + oData[6];
227     rMat3Data[7] = data_[7] + oData[7];
228     rMat3Data[8] = data_[8] + oData[8];
229 
230     return rMat3Add;
231 }
232 
233 template<typename T>
234 Matrix3<T> Matrix3<T>::operator-(const Matrix3<T>& other) const
235 {
236     return *this + (-other);
237 }
238 
239 template<typename T>
240 Matrix3<T> Matrix3<T>::operator-() const
241 {
242     Matrix3<T> rMat3Sub;
243     T* rMat3Data = rMat3Sub.data_;
244 
245     rMat3Data[0] = -data_[0];
246     rMat3Data[1] = -data_[1];
247     rMat3Data[2] = -data_[2];
248     rMat3Data[3] = -data_[3];
249     rMat3Data[4] = -data_[4];
250     rMat3Data[5] = -data_[5];
251     rMat3Data[6] = -data_[6];
252     rMat3Data[7] = -data_[7];
253     rMat3Data[8] = -data_[8];
254 
255     return rMat3Sub;
256 }
257 
258 template<typename T>
259 Matrix3<T> Matrix3<T>::operator*(const Matrix3<T>& other) const
260 {
261     return Multiply(other);
262 }
263 
264 template<typename T>
265 Vector3<T> Matrix3<T>::operator*(const Vector3<T>& other) const
266 {
267     Vector3<T> rMulti;
268     T* rData = rMulti.data_;
269     const T* oData = other.data_;
270     rData[0] = data_[0] * oData[0] + data_[3] * oData[1] + data_[6] * oData[2];
271 
272     rData[1] = data_[1] * oData[0] + data_[4] * oData[1] + data_[7] * oData[2];
273 
274     rData[2] = data_[2] * oData[0] + data_[5] * oData[1] + data_[8] * oData[2];
275     return rMulti;
276 }
277 
278 template<typename T>
279 Matrix3<T> Matrix3<T>::operator*(T scale) const
280 {
281     Matrix3<T> rMulti;
282     T* rData = rMulti.data_;
283     rData[0] = data_[0] * scale;
284     rData[1] = data_[1] * scale;
285     rData[2] = data_[2] * scale;
286     rData[3] = data_[3] * scale;
287     rData[4] = data_[4] * scale;
288     rData[5] = data_[5] * scale;
289     rData[6] = data_[6] * scale;
290     rData[7] = data_[7] * scale;
291     rData[8] = data_[8] * scale;
292 
293     return rMulti;
294 }
295 
296 template<typename T>
297 T* Matrix3<T>::operator[](int col)
298 {
299     return &data_[col * 3];
300 }
301 
302 template<typename T>
303 Matrix3<T>& Matrix3<T>::operator=(const Matrix3<T>& other)
304 {
305     const T* oMat3Data = other.data_;
306     data_[0] = oMat3Data[0];
307     data_[1] = oMat3Data[1];
308     data_[2] = oMat3Data[2];
309     data_[3] = oMat3Data[3];
310     data_[4] = oMat3Data[4];
311     data_[5] = oMat3Data[5];
312     data_[6] = oMat3Data[6];
313     data_[7] = oMat3Data[7];
314     data_[8] = oMat3Data[8];
315 
316     return *this;
317 }
318 
319 template<typename T>
320 Matrix3<T>& Matrix3<T>::operator+=(const Matrix3<T>& other)
321 {
322     const T* oData = other.data_;
323 
324     data_[0] += oData[0];
325     data_[1] += oData[1];
326     data_[2] += oData[2];
327     data_[3] += oData[3];
328     data_[4] += oData[4];
329     data_[5] += oData[5];
330     data_[6] += oData[6];
331     data_[7] += oData[7];
332     data_[8] += oData[8];
333 
334     return *this;
335 }
336 
337 template<typename T>
338 Matrix3<T>& Matrix3<T>::operator-=(const Matrix3<T>& other)
339 {
340     const T* oData = other.data_;
341 
342     data_[0] -= oData[0];
343     data_[1] -= oData[1];
344     data_[2] -= oData[2];
345     data_[3] -= oData[3];
346     data_[4] -= oData[4];
347     data_[5] -= oData[5];
348     data_[6] -= oData[6];
349     data_[7] -= oData[7];
350     data_[8] -= oData[8];
351 
352     return *this;
353 }
354 
355 template<typename T>
356 Matrix3<T>& Matrix3<T>::operator*=(const Matrix3<T>& other)
357 {
358     return (*this = *this * other);
359 }
360 
361 template<typename T>
362 Matrix3<T>& Matrix3<T>::operator*=(T scale)
363 {
364     data_[0] *= scale;
365     data_[1] *= scale;
366     data_[2] *= scale;
367     data_[3] *= scale;
368     data_[4] *= scale;
369     data_[5] *= scale;
370     data_[6] *= scale;
371     data_[7] *= scale;
372     data_[8] *= scale;
373     return *this;
374 }
375 
376 template<typename T>
377 bool Matrix3<T>::operator==(const Matrix3& other) const
378 {
379     const T* oData = other.data_;
380 
381     return (MMI_EQ<T>(data_[0], oData[0])) && (MMI_EQ<T>(data_[1], oData[1])) &&
382            (MMI_EQ<T>(data_[2], oData[2])) && (MMI_EQ<T>(data_[3], oData[3])) &&
383            (MMI_EQ<T>(data_[4], oData[4])) && (MMI_EQ<T>(data_[5], oData[5])) &&
384            (MMI_EQ<T>(data_[6], oData[6])) && (MMI_EQ<T>(data_[7], oData[7])) && (MMI_EQ<T>(data_[8], oData[8]));
385 }
386 
387 template<typename T>
388 bool Matrix3<T>::operator!=(const Matrix3& other) const
389 {
390     return !operator==(other);
391 }
392 
393 template<typename T>
IsNearEqual(const Matrix3 & other,T threshold)394 bool Matrix3<T>::IsNearEqual(const Matrix3& other, T threshold) const
395 {
396     const T* otherData = other.data_;
397     auto result = std::equal(data_, data_ + 8, otherData,
398         [&threshold](const T& left, const T& right) { return MMI_EQ<T>(left, right, threshold); });
399     return result;
400 }
401 
402 template<typename T>
GetData()403 inline T* Matrix3<T>::GetData()
404 {
405     return data_;
406 }
407 
408 template<typename T>
GetConstData()409 const T* Matrix3<T>::GetConstData() const
410 {
411     return data_;
412 }
413 
414 template<typename T>
Determinant()415 T Matrix3<T>::Determinant() const
416 {
417     T x = data_[0] * ((data_[4] * data_[8]) - (data_[5] * data_[7]));
418     T y = data_[1] * ((data_[3] * data_[8]) - (data_[5] * data_[6]));
419     T z = data_[2] * ((data_[3] * data_[7]) - (data_[4] * data_[6]));
420     return x - y + z;
421 }
422 
423 template<typename T>
Transpose()424 Matrix3<T> Matrix3<T>::Transpose() const
425 {
426     Matrix3<T> rTrans;
427     T* rData = rTrans.data_;
428     rData[0] = data_[0];
429     rData[1] = data_[3];
430     rData[2] = data_[6];
431     rData[3] = data_[1];
432     rData[4] = data_[4];
433     rData[5] = data_[7];
434     rData[6] = data_[2];
435     rData[7] = data_[5];
436     rData[8] = data_[8];
437     return rTrans;
438 }
439 
440 template<typename T>
Translate(const Vector2<T> & vec)441 Matrix3<T> Matrix3<T>::Translate(const Vector2<T>& vec) const
442 {
443     Matrix3<T> rTrans(*this);
444     T* rData = rTrans.data_;
445 
446     rData[6] = data_[0] * vec[0] + data_[3] * vec[1] + data_[6];
447     rData[7] = data_[1] * vec[0] + data_[4] * vec[1] + data_[7];
448     rData[8] = data_[2] * vec[0] + data_[5] * vec[1] + data_[8];
449     return rTrans;
450 }
451 
452 template<typename T>
Rotate(T angle)453 Matrix3<T> Matrix3<T>::Rotate(T angle) const
454 {
455     T a = angle;
456     T c = cos(a);
457     T s = sin(a);
458 
459     Matrix3<T> rRotate(*this);
460     T* rData = rRotate.data_;
461     rData[0] = data_[0] * c + data_[3] * s;
462     rData[1] = data_[1] * c + data_[4] * s;
463     rData[2] = data_[2] * c + data_[5] * s;
464 
465     rData[3] = data_[0] * -s + data_[3] * c;
466     rData[4] = data_[1] * -s + data_[4] * c;
467     rData[5] = data_[2] * -s + data_[5] * c;
468     return rRotate;
469 }
470 
471 template<typename T>
Rotate(T angle,T pivotx,T pivoty)472 Matrix3<T> Matrix3<T>::Rotate(T angle, T pivotx, T pivoty) const
473 {
474     T a = angle;
475     T c = cos(a);
476     T s = sin(a);
477     T dx = s * pivoty + (1 - c) * pivotx;
478     T dy = -s * pivotx + (1 - c) * pivoty;
479 
480     Matrix3<T> rRotate(*this);
481     T* rData = rRotate.data_;
482     rData[0] = data_[0] * c + data_[3] * s;
483     rData[1] = data_[1] * c + data_[4] * s;
484     rData[2] = data_[2] * c + data_[5] * s;
485 
486     rData[3] = data_[0] * -s + data_[3] * c;
487     rData[4] = data_[1] * -s + data_[4] * c;
488     rData[5] = data_[2] * -s + data_[5] * c;
489 
490     rData[6] = data_[0] * dx + data_[3] * dy + data_[6];
491     rData[7] = data_[1] * dx + data_[4] * dy + data_[7];
492     rData[8] = data_[2] * dx + data_[5] * dy + data_[8];
493     return rRotate;
494 }
495 
496 template<typename T>
Scale(const Vector2<T> & vec)497 Matrix3<T> Matrix3<T>::Scale(const Vector2<T>& vec) const
498 {
499     Matrix3<T> rScale(*this);
500     T* rData = rScale.data_;
501     rData[0] = data_[0] * vec[0];
502     rData[1] = data_[1] * vec[0];
503     rData[2] = data_[2] * vec[0];
504 
505     rData[3] = data_[3] * vec[1];
506     rData[4] = data_[4] * vec[1];
507     rData[5] = data_[5] * vec[1];
508     return rScale;
509 }
510 
511 template<typename T>
Scale(const Vector2<T> & vec,T pivotx,T pivoty)512 Matrix3<T> Matrix3<T>::Scale(const Vector2<T>& vec, T pivotx, T pivoty) const
513 {
514     T dx = pivotx - vec[0] * pivotx;
515     T dy = pivoty - vec[1] * pivoty;
516 
517     Matrix3<T> rScale(*this);
518     T* rData = rScale.data_;
519     rData[0] = data_[0] * vec[0];
520     rData[1] = data_[1] * vec[0];
521     rData[2] = data_[2] * vec[0];
522 
523     rData[3] = data_[3] * vec[1];
524     rData[4] = data_[4] * vec[1];
525     rData[5] = data_[5] * vec[1];
526 
527     rData[6] = data_[0] * dx + data_[3] * dy + data_[6];
528     rData[7] = data_[1] * dx + data_[4] * dy + data_[7];
529     rData[8] = data_[2] * dx + data_[5] * dy + data_[8];
530     return rScale;
531 }
532 
533 template<typename T>
ShearX(T y)534 Matrix3<T> Matrix3<T>::ShearX(T y) const
535 {
536     Matrix3<T> rShear(Matrix3<T>::IDENTITY);
537     rShear.data_[1] = y;
538     return (*this) * rShear;
539 }
540 
541 template<typename T>
ShearY(T x)542 Matrix3<T> Matrix3<T>::ShearY(T x) const
543 {
544     Matrix3<T> rShear(Matrix3<T>::IDENTITY);
545     rShear.data_[3] = x;
546     return (*this) * rShear;
547 }
548 } // namespace Rosen
549 } // namespace OHOS
550 #endif // RENDER_SERVICE_CLIENT_CORE_COMMON_RS_MATRIX3_H
551