123b3eb3cSopenharmony_ci/*
223b3eb3cSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
323b3eb3cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
423b3eb3cSopenharmony_ci * you may not use this file except in compliance with the License.
523b3eb3cSopenharmony_ci * You may obtain a copy of the License at
623b3eb3cSopenharmony_ci *
723b3eb3cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
823b3eb3cSopenharmony_ci *
923b3eb3cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1023b3eb3cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1123b3eb3cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1223b3eb3cSopenharmony_ci * See the License for the specific language governing permissions and
1323b3eb3cSopenharmony_ci * limitations under the License.
1423b3eb3cSopenharmony_ci */
1523b3eb3cSopenharmony_ci
1623b3eb3cSopenharmony_ci#include "base/geometry/matrix3.h"
1723b3eb3cSopenharmony_ci
1823b3eb3cSopenharmony_cinamespace OHOS::Ace {
1923b3eb3cSopenharmony_civoid Matrix3::SetEntry(int32_t row, int32_t col, double value)
2023b3eb3cSopenharmony_ci{
2123b3eb3cSopenharmony_ci    if ((row < 0 || row >= DIMENSION) || (col < 0 || col >= DIMENSION)) {
2223b3eb3cSopenharmony_ci        return;
2323b3eb3cSopenharmony_ci    }
2423b3eb3cSopenharmony_ci    matrix3X3_[row][col] = value;
2523b3eb3cSopenharmony_ci}
2623b3eb3cSopenharmony_ci
2723b3eb3cSopenharmony_cibool Matrix3::Invert(Matrix3& matrix) const
2823b3eb3cSopenharmony_ci{
2923b3eb3cSopenharmony_ci    static const double diff = 1e-20;
3023b3eb3cSopenharmony_ci    double val1 = matrix3X3_[0][0] * matrix3X3_[1][1] * matrix3X3_[2][2];
3123b3eb3cSopenharmony_ci    double val2 = matrix3X3_[0][0] * matrix3X3_[1][2] * matrix3X3_[2][1];
3223b3eb3cSopenharmony_ci    double val3 = matrix3X3_[1][0] * matrix3X3_[0][1] * matrix3X3_[2][2];
3323b3eb3cSopenharmony_ci    double val4 = matrix3X3_[1][0] * matrix3X3_[0][2] * matrix3X3_[2][1];
3423b3eb3cSopenharmony_ci    double val5 = matrix3X3_[2][0] * matrix3X3_[0][1] * matrix3X3_[1][2];
3523b3eb3cSopenharmony_ci    double val6 = matrix3X3_[2][0] * matrix3X3_[0][2] * matrix3X3_[1][1];
3623b3eb3cSopenharmony_ci    double detA = val1 - val2 - val3 + val4 + val5 - val6;
3723b3eb3cSopenharmony_ci    if (NearZero(detA, diff)) {
3823b3eb3cSopenharmony_ci        return false;
3923b3eb3cSopenharmony_ci    }
4023b3eb3cSopenharmony_ci    detA = 1.0 / detA;
4123b3eb3cSopenharmony_ci    // a11a22 - a12a21
4223b3eb3cSopenharmony_ci    matrix[0][0] = matrix3X3_[1][1] * matrix3X3_[2][2] - matrix3X3_[1][2] * matrix3X3_[2][1];
4323b3eb3cSopenharmony_ci    // a20a21 - a01a22
4423b3eb3cSopenharmony_ci    matrix[0][1] = matrix3X3_[0][2] * matrix3X3_[2][1] - matrix3X3_[0][1] * matrix3X3_[2][2];
4523b3eb3cSopenharmony_ci    // a01a12 - a02a11
4623b3eb3cSopenharmony_ci    matrix[0][2] = matrix3X3_[0][1] * matrix3X3_[1][2] - matrix3X3_[0][2] * matrix3X3_[1][1];
4723b3eb3cSopenharmony_ci    // a12a20 - a10a22
4823b3eb3cSopenharmony_ci    matrix[1][0] = matrix3X3_[1][2] * matrix3X3_[2][0] - matrix3X3_[1][0] * matrix3X3_[2][2];
4923b3eb3cSopenharmony_ci    // a00a22 - a02a20
5023b3eb3cSopenharmony_ci    matrix[1][1] = matrix3X3_[0][0] * matrix3X3_[2][2] - matrix3X3_[0][2] * matrix3X3_[2][0];
5123b3eb3cSopenharmony_ci    // a10a02 - a00a12
5223b3eb3cSopenharmony_ci    matrix[1][2] = matrix3X3_[1][0] * matrix3X3_[0][2] - matrix3X3_[0][0] * matrix3X3_[1][2];
5323b3eb3cSopenharmony_ci    // a10a21 - a11a20
5423b3eb3cSopenharmony_ci    matrix[2][0] = matrix3X3_[1][0] * matrix3X3_[2][1] - matrix3X3_[1][1] * matrix3X3_[2][0];
5523b3eb3cSopenharmony_ci    // a01a20 - a00a21
5623b3eb3cSopenharmony_ci    matrix[2][1] = matrix3X3_[0][1] * matrix3X3_[2][0] - matrix3X3_[0][0] * matrix3X3_[2][1];
5723b3eb3cSopenharmony_ci    // a00a11 - a10a01
5823b3eb3cSopenharmony_ci    matrix[2][2] = matrix3X3_[0][0] * matrix3X3_[1][1] - matrix3X3_[1][0] * matrix3X3_[0][1];
5923b3eb3cSopenharmony_ci    // invert
6023b3eb3cSopenharmony_ci    matrix* detA;
6123b3eb3cSopenharmony_ci    return true;
6223b3eb3cSopenharmony_ci}
6323b3eb3cSopenharmony_ci
6423b3eb3cSopenharmony_ciMatrix3N Matrix3::operator*(const Matrix3N& matrix) const
6523b3eb3cSopenharmony_ci{
6623b3eb3cSopenharmony_ci    int32_t columns = matrix.GetColNum();
6723b3eb3cSopenharmony_ci    Matrix3N Matrix3n { columns };
6823b3eb3cSopenharmony_ci    for (auto i = 0; i < DIMENSION; i++) {
6923b3eb3cSopenharmony_ci        for (auto j = 0; j < columns; j++) {
7023b3eb3cSopenharmony_ci            double value = 0.0;
7123b3eb3cSopenharmony_ci            for (auto k = 0; k < DIMENSION; k++) {
7223b3eb3cSopenharmony_ci                value += matrix3X3_[i][k] * matrix[k][j];
7323b3eb3cSopenharmony_ci            }
7423b3eb3cSopenharmony_ci            Matrix3n[i][j] = value;
7523b3eb3cSopenharmony_ci        }
7623b3eb3cSopenharmony_ci    }
7723b3eb3cSopenharmony_ci    return Matrix3n;
7823b3eb3cSopenharmony_ci}
7923b3eb3cSopenharmony_ci
8023b3eb3cSopenharmony_ciMatrix3 Matrix3::Transpose() const
8123b3eb3cSopenharmony_ci{
8223b3eb3cSopenharmony_ci    Matrix3 matrix;
8323b3eb3cSopenharmony_ci    for (auto i = 0; i < DIMENSION; i++) {
8423b3eb3cSopenharmony_ci        for (auto j = 0; j < DIMENSION; j++) {
8523b3eb3cSopenharmony_ci            matrix[j][i] = matrix3X3_[i][j];
8623b3eb3cSopenharmony_ci        }
8723b3eb3cSopenharmony_ci    }
8823b3eb3cSopenharmony_ci    return matrix;
8923b3eb3cSopenharmony_ci}
9023b3eb3cSopenharmony_ci
9123b3eb3cSopenharmony_cistd::vector<double> Matrix3::MapScalars(const std::vector<double>& src) const
9223b3eb3cSopenharmony_ci{
9323b3eb3cSopenharmony_ci    std::vector<double> value(DIMENSION, 0);
9423b3eb3cSopenharmony_ci    if (static_cast<int32_t>(src.size()) != DIMENSION) {
9523b3eb3cSopenharmony_ci        return value;
9623b3eb3cSopenharmony_ci    }
9723b3eb3cSopenharmony_ci    for (int32_t i = 0; i < DIMENSION; i++) {
9823b3eb3cSopenharmony_ci        double item = 0.0;
9923b3eb3cSopenharmony_ci        for (int32_t j = 0; j < DIMENSION; j++) {
10023b3eb3cSopenharmony_ci            item = item + matrix3X3_[i][j] * src[j];
10123b3eb3cSopenharmony_ci        }
10223b3eb3cSopenharmony_ci        value[i] = item;
10323b3eb3cSopenharmony_ci    }
10423b3eb3cSopenharmony_ci    return value;
10523b3eb3cSopenharmony_ci}
10623b3eb3cSopenharmony_ci
10723b3eb3cSopenharmony_cibool Matrix3::MapScalars(const std::vector<double>& src, std::vector<double>& result) const
10823b3eb3cSopenharmony_ci{
10923b3eb3cSopenharmony_ci    if (static_cast<int32_t>(src.size()) != DIMENSION) {
11023b3eb3cSopenharmony_ci        return false;
11123b3eb3cSopenharmony_ci    }
11223b3eb3cSopenharmony_ci    result.resize(DIMENSION, 0);
11323b3eb3cSopenharmony_ci    for (int32_t i = 0; i < DIMENSION; i++) {
11423b3eb3cSopenharmony_ci        double item = 0.0;
11523b3eb3cSopenharmony_ci        for (int32_t j = 0; j < DIMENSION; j++) {
11623b3eb3cSopenharmony_ci            item = item + matrix3X3_[i][j] * src[j];
11723b3eb3cSopenharmony_ci        }
11823b3eb3cSopenharmony_ci        result[i] = item;
11923b3eb3cSopenharmony_ci    }
12023b3eb3cSopenharmony_ci    return true;
12123b3eb3cSopenharmony_ci}
12223b3eb3cSopenharmony_ci
12323b3eb3cSopenharmony_ciMatrix3N::Matrix3N(int32_t columns) : columns_(columns)
12423b3eb3cSopenharmony_ci{
12523b3eb3cSopenharmony_ci    Matrix3n_.resize(DIMENSION, std::vector<double>(columns_, 0));
12623b3eb3cSopenharmony_ci}
12723b3eb3cSopenharmony_ci
12823b3eb3cSopenharmony_cibool Matrix3N::SetEntry(int32_t row, int32_t col, double value)
12923b3eb3cSopenharmony_ci{
13023b3eb3cSopenharmony_ci    if (row >= DIMENSION || col >= columns_) {
13123b3eb3cSopenharmony_ci        return false;
13223b3eb3cSopenharmony_ci    }
13323b3eb3cSopenharmony_ci    Matrix3n_[row][col] = value;
13423b3eb3cSopenharmony_ci    return true;
13523b3eb3cSopenharmony_ci}
13623b3eb3cSopenharmony_ci
13723b3eb3cSopenharmony_ciMatrix3 Matrix3N::operator*(const MatrixN3& matrix) const
13823b3eb3cSopenharmony_ci{
13923b3eb3cSopenharmony_ci    Matrix3 Matrix3;
14023b3eb3cSopenharmony_ci    if (columns_ != matrix.GetRowNum()) {
14123b3eb3cSopenharmony_ci        return Matrix3;
14223b3eb3cSopenharmony_ci    }
14323b3eb3cSopenharmony_ci    for (auto i = 0; i < DIMENSION; i++) {
14423b3eb3cSopenharmony_ci        for (auto j = 0; j < DIMENSION; j++) {
14523b3eb3cSopenharmony_ci            double value = 0.0;
14623b3eb3cSopenharmony_ci            for (auto k = 0; k < columns_; k++) {
14723b3eb3cSopenharmony_ci                value += Matrix3n_[i][k] * matrix[k][j];
14823b3eb3cSopenharmony_ci            }
14923b3eb3cSopenharmony_ci            Matrix3[i][j] = value;
15023b3eb3cSopenharmony_ci        }
15123b3eb3cSopenharmony_ci    }
15223b3eb3cSopenharmony_ci    return Matrix3;
15323b3eb3cSopenharmony_ci}
15423b3eb3cSopenharmony_ci
15523b3eb3cSopenharmony_ciMatrixN3 Matrix3N::Transpose() const
15623b3eb3cSopenharmony_ci{
15723b3eb3cSopenharmony_ci    MatrixN3 matrix { columns_ };
15823b3eb3cSopenharmony_ci    for (auto i = 0; i < DIMENSION; i++) {
15923b3eb3cSopenharmony_ci        for (auto j = 0; j < columns_; j++) {
16023b3eb3cSopenharmony_ci            matrix[j][i] = Matrix3n_[i][j];
16123b3eb3cSopenharmony_ci        }
16223b3eb3cSopenharmony_ci    }
16323b3eb3cSopenharmony_ci    return matrix;
16423b3eb3cSopenharmony_ci}
16523b3eb3cSopenharmony_ci
16623b3eb3cSopenharmony_cistd::vector<double> Matrix3N::MapScalars(const std::vector<double>& src) const
16723b3eb3cSopenharmony_ci{
16823b3eb3cSopenharmony_ci    std::vector<double> value(DIMENSION, 0);
16923b3eb3cSopenharmony_ci    if (static_cast<int32_t>(src.size()) != columns_) {
17023b3eb3cSopenharmony_ci        return value;
17123b3eb3cSopenharmony_ci    }
17223b3eb3cSopenharmony_ci    for (int32_t i = 0; i < DIMENSION; i++) {
17323b3eb3cSopenharmony_ci        double item = 0.0;
17423b3eb3cSopenharmony_ci        for (int32_t j = 0; j < columns_; j++) {
17523b3eb3cSopenharmony_ci            item = item + Matrix3n_[i][j] * src[j];
17623b3eb3cSopenharmony_ci        }
17723b3eb3cSopenharmony_ci        value[i] = item;
17823b3eb3cSopenharmony_ci    }
17923b3eb3cSopenharmony_ci    return value;
18023b3eb3cSopenharmony_ci}
18123b3eb3cSopenharmony_ci
18223b3eb3cSopenharmony_cibool Matrix3N::MapScalars(const std::vector<double>& src, std::vector<double>& result) const
18323b3eb3cSopenharmony_ci{
18423b3eb3cSopenharmony_ci    if (static_cast<int32_t>(src.size()) != columns_) {
18523b3eb3cSopenharmony_ci        return false;
18623b3eb3cSopenharmony_ci    }
18723b3eb3cSopenharmony_ci    result.resize(DIMENSION, 0);
18823b3eb3cSopenharmony_ci    for (int32_t i = 0; i < DIMENSION; i++) {
18923b3eb3cSopenharmony_ci        double item = 0.0;
19023b3eb3cSopenharmony_ci        for (int32_t j = 0; j < columns_; j++) {
19123b3eb3cSopenharmony_ci            item = item + Matrix3n_[i][j] * src[j];
19223b3eb3cSopenharmony_ci        }
19323b3eb3cSopenharmony_ci        result[i] = item;
19423b3eb3cSopenharmony_ci    }
19523b3eb3cSopenharmony_ci    return true;
19623b3eb3cSopenharmony_ci}
19723b3eb3cSopenharmony_ci
19823b3eb3cSopenharmony_ciMatrixN3::MatrixN3(int32_t rows) : rows_(rows)
19923b3eb3cSopenharmony_ci{
20023b3eb3cSopenharmony_ci    Matrixn3_.resize(rows, std::vector<double>(DIMENSION, 0));
20123b3eb3cSopenharmony_ci}
20223b3eb3cSopenharmony_ci
20323b3eb3cSopenharmony_cibool MatrixN3::SetEntry(int32_t row, int32_t col, double value)
20423b3eb3cSopenharmony_ci{
20523b3eb3cSopenharmony_ci    if (row >= rows_ || col >= DIMENSION) {
20623b3eb3cSopenharmony_ci        return false;
20723b3eb3cSopenharmony_ci    }
20823b3eb3cSopenharmony_ci    Matrixn3_[row][col] = value;
20923b3eb3cSopenharmony_ci    return true;
21023b3eb3cSopenharmony_ci}
21123b3eb3cSopenharmony_ci
21223b3eb3cSopenharmony_ciMatrix3N MatrixN3::Transpose() const
21323b3eb3cSopenharmony_ci{
21423b3eb3cSopenharmony_ci    Matrix3N matrix { rows_ };
21523b3eb3cSopenharmony_ci    for (auto i = 0; i < DIMENSION; i++) {
21623b3eb3cSopenharmony_ci        for (auto j = 0; j < rows_; j++) {
21723b3eb3cSopenharmony_ci            matrix[i][j] = Matrixn3_[j][i];
21823b3eb3cSopenharmony_ci        }
21923b3eb3cSopenharmony_ci    }
22023b3eb3cSopenharmony_ci    return matrix;
22123b3eb3cSopenharmony_ci}
22223b3eb3cSopenharmony_ci
22323b3eb3cSopenharmony_cistd::vector<double> MatrixN3::MapScalars(const std::vector<double>& src) const
22423b3eb3cSopenharmony_ci{
22523b3eb3cSopenharmony_ci    std::vector<double> value(rows_, 0);
22623b3eb3cSopenharmony_ci    if (static_cast<int32_t>(src.size()) != DIMENSION) {
22723b3eb3cSopenharmony_ci        return value;
22823b3eb3cSopenharmony_ci    }
22923b3eb3cSopenharmony_ci    for (int32_t i = 0; i < rows_; i++) {
23023b3eb3cSopenharmony_ci        double item = 0.0;
23123b3eb3cSopenharmony_ci        for (int32_t j = 0; j < DIMENSION; j++) {
23223b3eb3cSopenharmony_ci            item = item + Matrixn3_[i][j] * src[j];
23323b3eb3cSopenharmony_ci        }
23423b3eb3cSopenharmony_ci        value[i] = item;
23523b3eb3cSopenharmony_ci    }
23623b3eb3cSopenharmony_ci    return value;
23723b3eb3cSopenharmony_ci}
23823b3eb3cSopenharmony_ci} // namespace OHOS::Ace
239