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