mirror of
https://github.com/openharmony/ace_ace_engine.git
synced 2026-07-19 14:43:36 -04:00
fix the problem of velocity tracker
Signed-off-by: yan-shuifeng <yanshuifeng@huawei.com> Change-Id: Ifc40ac8dbb99adacbfac3b9fb2f9c9a781b2efe0
This commit is contained in:
@@ -68,7 +68,7 @@ TouchPoint ConvertTouchPoint(const MMI::PointerEvent::PointerItem& pointerItem)
|
||||
touchPoint.size = std::max(pointerItem.GetWidth(), pointerItem.GetHeight()) / 2.0;
|
||||
touchPoint.id = pointerItem.GetPointerId();
|
||||
touchPoint.force = pointerItem.GetPressure();
|
||||
touchPoint.downTime = TimeStamp(std::chrono::microseconds(pointerItem.GetDownTime()));
|
||||
touchPoint.downTime = TimeStamp(std::chrono::milliseconds(pointerItem.GetDownTime()));
|
||||
touchPoint.x = pointerItem.GetLocalX();
|
||||
touchPoint.y = pointerItem.GetLocalY();
|
||||
touchPoint.isPressed = pointerItem.IsPressed();
|
||||
@@ -100,8 +100,8 @@ TouchEvent ConvertTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEv
|
||||
return TouchEvent();
|
||||
}
|
||||
auto touchPoint = ConvertTouchPoint(item);
|
||||
std::chrono::microseconds micros(pointerEvent->GetActionTime());
|
||||
TimeStamp time(micros);
|
||||
std::chrono::milliseconds milliseconds(pointerEvent->GetActionTime());
|
||||
TimeStamp time(milliseconds);
|
||||
TouchEvent event { touchPoint.id, touchPoint.x, touchPoint.y, TouchType::UNKNOWN, time, touchPoint.size,
|
||||
touchPoint.force, pointerEvent->GetDeviceId() };
|
||||
int32_t orgDevice = pointerEvent->GetSourceType();
|
||||
|
||||
@@ -31,6 +31,8 @@ template("ace_base_source_set") {
|
||||
sources = [
|
||||
"geometry/animatable_dimension.cpp",
|
||||
"geometry/animatable_matrix4.cpp",
|
||||
"geometry/least_square_impl.cpp",
|
||||
"geometry/matrix3.cpp",
|
||||
"geometry/matrix4.cpp",
|
||||
"geometry/quaternion.cpp",
|
||||
"geometry/transform_util.cpp",
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "base/geometry/least_square_impl.h"
|
||||
|
||||
#include "base/geometry/matrix3.h"
|
||||
#include "base/geometry/matrix4.h"
|
||||
#include "base/log/log.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
bool LeastSquareImpl::GetLeastSquareParams(std::vector<double>& params)
|
||||
{
|
||||
if (xVals_.size() <= 1 || ((paramsNum_ != Matrix3::DIMENSION) && (paramsNum_ != Matrix4::DIMENSION))) {
|
||||
LOGE("size is invalid, %{public}d, %{public}d", static_cast<int32_t>(xVals_.size()), paramsNum_);
|
||||
return false;
|
||||
}
|
||||
params.resize(paramsNum_, 0);
|
||||
if (isResolved_) {
|
||||
params.assign(params_.begin(), params_.end());
|
||||
return true;
|
||||
}
|
||||
auto countNum = std::min(countNum_, static_cast<int32_t>(std::distance(xVals_.begin(), xVals_.end())));
|
||||
std::vector<double> xVals;
|
||||
xVals.resize(countNum, 0);
|
||||
std::vector<double> yVals;
|
||||
yVals.resize(countNum, 0);
|
||||
int32_t size = countNum - 1;
|
||||
for (auto iter = xVals_.rbegin(); iter != xVals_.rend(); iter++) {
|
||||
xVals[size] = *iter;
|
||||
size--;
|
||||
if (size < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
size = countNum - 1;
|
||||
for (auto iter = yVals_.rbegin(); iter != yVals_.rend(); iter++) {
|
||||
yVals[size] = *iter;
|
||||
size--;
|
||||
if (size < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (paramsNum_ == Matrix3::DIMENSION) {
|
||||
MatrixN3 matrixn3 { countNum };
|
||||
for (auto i = 0; i < countNum; i++) {
|
||||
const auto& value = xVals[i];
|
||||
matrixn3[i][2] = 1;
|
||||
matrixn3[i][1] = value;
|
||||
matrixn3[i][0] = value * value;
|
||||
}
|
||||
Matrix3 invert;
|
||||
auto transpose = matrixn3.Transpose();
|
||||
if (!(transpose * matrixn3).Invert(invert)) {
|
||||
LOGE("fail to invert");
|
||||
return false;
|
||||
}
|
||||
auto matrix3n = invert * transpose;
|
||||
auto ret = matrix3n.MapScalars(yVals, params);
|
||||
if (ret) {
|
||||
params_.assign(params.begin(), params.end());
|
||||
isResolved_ = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
MatrixN4 matrixn4 { countNum };
|
||||
for (auto i = 0; i < countNum; i++) {
|
||||
const auto& value = xVals[i];
|
||||
matrixn4[i][3] = 1;
|
||||
matrixn4[i][2] = value;
|
||||
matrixn4[i][1] = value * value;
|
||||
matrixn4[i][0] = value * value * value;
|
||||
}
|
||||
auto transpose = matrixn4.Transpose();
|
||||
auto inversMatrix4 = Matrix4::Invert(transpose * matrixn4);
|
||||
auto matrix4n = inversMatrix4 * transpose;
|
||||
auto ret = matrix4n.MapScalars(yVals, params);
|
||||
if (ret) {
|
||||
params_.assign(params.begin(), params.end());
|
||||
isResolved_ = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} // namespace OHOS::Ace
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_LEAST_SQUARE_IMPL_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_LEAST_SQUARE_IMPL_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/utils/macros.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
/**
|
||||
* @brief Least square method of four parametres.
|
||||
* the function template is a3 * x^3 + a2 * x^2 + a1 * x + a0 = y with four;
|
||||
* the function template is 0 * x^3 + a2 * x^2 + a1 * x + a0 = y with three.
|
||||
*/
|
||||
class ACE_EXPORT LeastSquareImpl {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Least Square Impl object.
|
||||
* @param paramsNum the right number is 4 or 3.
|
||||
*/
|
||||
explicit LeastSquareImpl(int32_t paramsNum) : paramsNum_(paramsNum) {}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Least Square Impl object.
|
||||
* @param paramsNum the right number is 4 or 3.
|
||||
*/
|
||||
LeastSquareImpl(int32_t paramsNum, int32_t countNum) : paramsNum_(paramsNum), countNum_(countNum) {}
|
||||
|
||||
LeastSquareImpl() = default;
|
||||
~LeastSquareImpl() = default;
|
||||
|
||||
void UpdatePoint(double xVal, double yVal)
|
||||
{
|
||||
isResolved_ = false;
|
||||
xVals_.emplace_back(xVal);
|
||||
yVals_.emplace_back(yVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Count Num which to compute.
|
||||
*
|
||||
* @param countNum the compute number.
|
||||
*/
|
||||
void SetCountNum(int32_t countNum)
|
||||
{
|
||||
countNum_ = countNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the Least Square Params object
|
||||
*
|
||||
* @param params the four values of vector.
|
||||
* @return true get the least square result.
|
||||
* @return false falied to get the least square result.
|
||||
*/
|
||||
bool GetLeastSquareParams(std::vector<double>& params);
|
||||
|
||||
inline const std::vector<double>& GetXVals() const
|
||||
{
|
||||
return xVals_;
|
||||
}
|
||||
|
||||
inline const std::vector<double>& GetYVals() const
|
||||
{
|
||||
return yVals_;
|
||||
}
|
||||
|
||||
inline int32_t GetTrackNum() const
|
||||
{
|
||||
return xVals_.size();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
xVals_.clear();
|
||||
yVals_.clear();
|
||||
params_.clear();
|
||||
isResolved_ = false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<double> xVals_;
|
||||
std::vector<double> yVals_;
|
||||
std::vector<double> params_;
|
||||
int32_t paramsNum_ = 4;
|
||||
int32_t countNum_ = 4;
|
||||
bool isResolved_ = false;
|
||||
};
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_LEAST_SQUARE_IMPL_H
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "base/geometry/matrix3.h"
|
||||
|
||||
#include "base/utils/utils.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
void Matrix3::SetEntry(int32_t row, int32_t col, double value)
|
||||
{
|
||||
if ((row < 0 || row >= DIMENSION) || (col < 0 || col >= DIMENSION)) {
|
||||
return;
|
||||
}
|
||||
matrix3X3_[row][col] = value;
|
||||
}
|
||||
|
||||
bool Matrix3::Invert(Matrix3& matrix) const
|
||||
{
|
||||
static const double diff = 1e-20;
|
||||
double val1 = matrix3X3_[0][0] * matrix3X3_[1][1] * matrix3X3_[2][2];
|
||||
double val2 = matrix3X3_[0][0] * matrix3X3_[1][2] * matrix3X3_[2][1];
|
||||
double val3 = matrix3X3_[1][0] * matrix3X3_[0][1] * matrix3X3_[2][2];
|
||||
double val4 = matrix3X3_[1][0] * matrix3X3_[0][2] * matrix3X3_[2][1];
|
||||
double val5 = matrix3X3_[2][0] * matrix3X3_[0][1] * matrix3X3_[1][2];
|
||||
double val6 = matrix3X3_[2][0] * matrix3X3_[0][2] * matrix3X3_[1][1];
|
||||
double detA = val1 - val2 - val3 + val4 + val5 - val6;
|
||||
if (NearZero(detA, diff)) {
|
||||
return false;
|
||||
}
|
||||
detA = 1.0 / detA;
|
||||
// a11a22 - a12a21
|
||||
matrix[0][0] = matrix3X3_[1][1] * matrix3X3_[2][2] - matrix3X3_[1][2] * matrix3X3_[2][1];
|
||||
// a20a21 - a01a22
|
||||
matrix[0][1] = matrix3X3_[0][2] * matrix3X3_[2][1] - matrix3X3_[0][1] * matrix3X3_[2][2];
|
||||
// a01a12 - a02a11
|
||||
matrix[0][2] = matrix3X3_[0][1] * matrix3X3_[1][2] - matrix3X3_[0][2] * matrix3X3_[1][1];
|
||||
// a12a20 - a10a22
|
||||
matrix[1][0] = matrix3X3_[1][2] * matrix3X3_[2][0] - matrix3X3_[1][0] * matrix3X3_[2][2];
|
||||
// a00a22 - a02a20
|
||||
matrix[1][1] = matrix3X3_[0][0] * matrix3X3_[2][2] - matrix3X3_[0][2] * matrix3X3_[2][0];
|
||||
// a10a02 - a00a12
|
||||
matrix[1][2] = matrix3X3_[1][0] * matrix3X3_[0][2] - matrix3X3_[0][0] * matrix3X3_[1][2];
|
||||
// a10a21 - a11a20
|
||||
matrix[2][0] = matrix3X3_[1][0] * matrix3X3_[2][1] - matrix3X3_[1][1] * matrix3X3_[2][0];
|
||||
// a01a20 - a00a21
|
||||
matrix[2][1] = matrix3X3_[0][1] * matrix3X3_[2][0] - matrix3X3_[0][0] * matrix3X3_[2][1];
|
||||
// a00a11 - a10a01
|
||||
matrix[2][2] = matrix3X3_[0][0] * matrix3X3_[1][1] - matrix3X3_[1][0] * matrix3X3_[0][1];
|
||||
// invert
|
||||
matrix* detA;
|
||||
return true;
|
||||
}
|
||||
|
||||
Matrix3N Matrix3::operator*(const Matrix3N& matrix) const
|
||||
{
|
||||
int32_t columns = matrix.GetColNum();
|
||||
Matrix3N Matrix3n { columns };
|
||||
for (auto i = 0; i < DIMENSION; i++) {
|
||||
for (auto j = 0; j < columns; j++) {
|
||||
double value = 0.0;
|
||||
for (auto k = 0; k < DIMENSION; k++) {
|
||||
value += matrix3X3_[i][k] * matrix[k][j];
|
||||
}
|
||||
Matrix3n[i][j] = value;
|
||||
}
|
||||
}
|
||||
return Matrix3n;
|
||||
}
|
||||
|
||||
Matrix3 Matrix3::Transpose() const
|
||||
{
|
||||
Matrix3 matrix;
|
||||
for (auto i = 0; i < DIMENSION; i++) {
|
||||
for (auto j = 0; j < DIMENSION; j++) {
|
||||
matrix[j][i] = matrix3X3_[i][j];
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
std::vector<double> Matrix3::MapScalars(const std::vector<double>& src) const
|
||||
{
|
||||
std::vector<double> value { DIMENSION, 0 };
|
||||
if (static_cast<int32_t>(src.size()) != DIMENSION) {
|
||||
return value;
|
||||
}
|
||||
for (int32_t i = 0; i < DIMENSION; i++) {
|
||||
double item = 0.0;
|
||||
for (int32_t j = 0; j < DIMENSION; j++) {
|
||||
item = item + matrix3X3_[i][j] * src[j];
|
||||
}
|
||||
value[i] = item;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool Matrix3::MapScalars(const std::vector<double>& src, std::vector<double>& result) const
|
||||
{
|
||||
if (static_cast<int32_t>(src.size()) != DIMENSION) {
|
||||
return false;
|
||||
}
|
||||
result.resize(DIMENSION, 0);
|
||||
for (int32_t i = 0; i < DIMENSION; i++) {
|
||||
double item = 0.0;
|
||||
for (int32_t j = 0; j < DIMENSION; j++) {
|
||||
item = item + matrix3X3_[i][j] * src[j];
|
||||
}
|
||||
result[i] = item;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Matrix3N::Matrix3N(int32_t columns) : columns_(columns)
|
||||
{
|
||||
Matrix3n_.resize(DIMENSION, std::vector<double>(columns_, 0));
|
||||
}
|
||||
|
||||
bool Matrix3N::SetEntry(int32_t row, int32_t col, double value)
|
||||
{
|
||||
if (row >= DIMENSION || col >= columns_) {
|
||||
return false;
|
||||
}
|
||||
Matrix3n_[row][col] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
Matrix3 Matrix3N::operator*(const MatrixN3& matrix) const
|
||||
{
|
||||
Matrix3 Matrix3;
|
||||
if (columns_ != matrix.GetRowNum()) {
|
||||
return Matrix3;
|
||||
}
|
||||
for (auto i = 0; i < DIMENSION; i++) {
|
||||
for (auto j = 0; j < DIMENSION; j++) {
|
||||
double value = 0.0;
|
||||
for (auto k = 0; k < columns_; k++) {
|
||||
value += Matrix3n_[i][k] * matrix[k][j];
|
||||
}
|
||||
Matrix3[i][j] = value;
|
||||
}
|
||||
}
|
||||
return Matrix3;
|
||||
}
|
||||
|
||||
MatrixN3 Matrix3N::Transpose() const
|
||||
{
|
||||
MatrixN3 matrix { columns_ };
|
||||
for (auto i = 0; i < DIMENSION; i++) {
|
||||
for (auto j = 0; j < columns_; j++) {
|
||||
matrix[j][i] = Matrix3n_[i][j];
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
std::vector<double> Matrix3N::MapScalars(const std::vector<double>& src) const
|
||||
{
|
||||
std::vector<double> value { DIMENSION, 0 };
|
||||
if (static_cast<int32_t>(src.size()) != columns_) {
|
||||
return value;
|
||||
}
|
||||
for (int32_t i = 0; i < DIMENSION; i++) {
|
||||
double item = 0.0;
|
||||
for (int32_t j = 0; j < columns_; j++) {
|
||||
item = item + Matrix3n_[i][j] * src[j];
|
||||
}
|
||||
value[i] = item;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool Matrix3N::MapScalars(const std::vector<double>& src, std::vector<double>& result) const
|
||||
{
|
||||
if (static_cast<int32_t>(src.size()) != columns_) {
|
||||
LOGE("failt to MapScalars, due to %{public}d, %{public}d", static_cast<int32_t>(src.size()), columns_);
|
||||
return false;
|
||||
}
|
||||
result.resize(DIMENSION, 0);
|
||||
for (int32_t i = 0; i < DIMENSION; i++) {
|
||||
double item = 0.0;
|
||||
for (int32_t j = 0; j < columns_; j++) {
|
||||
item = item + Matrix3n_[i][j] * src[j];
|
||||
}
|
||||
result[i] = item;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MatrixN3::MatrixN3(int32_t rows) : rows_(rows)
|
||||
{
|
||||
Matrixn3_.resize(rows, std::vector<double>(DIMENSION, 0));
|
||||
}
|
||||
|
||||
bool MatrixN3::SetEntry(int32_t row, int32_t col, double value)
|
||||
{
|
||||
if (row >= rows_ || col >= DIMENSION) {
|
||||
return false;
|
||||
}
|
||||
Matrixn3_[row][col] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
Matrix3N MatrixN3::Transpose() const
|
||||
{
|
||||
Matrix3N matrix { rows_ };
|
||||
for (auto i = 0; i < DIMENSION; i++) {
|
||||
for (auto j = 0; j < rows_; j++) {
|
||||
matrix[i][j] = Matrixn3_[j][i];
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
std::vector<double> MatrixN3::MapScalars(const std::vector<double>& src) const
|
||||
{
|
||||
std::vector<double> value { rows_, 0 };
|
||||
if (static_cast<int32_t>(src.size()) != DIMENSION) {
|
||||
return value;
|
||||
}
|
||||
for (int32_t i = 0; i < rows_; i++) {
|
||||
double item = 0.0;
|
||||
for (int32_t j = 0; j < DIMENSION; j++) {
|
||||
item = item + Matrixn3_[i][j] * src[j];
|
||||
}
|
||||
value[i] = item;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
} // namespace OHOS::Ace
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_MATRIX3_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_MATRIX3_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/geometry/point.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
class Matrix3N;
|
||||
class MatrixN3;
|
||||
|
||||
class ACE_EXPORT Matrix3 {
|
||||
public:
|
||||
// Matrix dimension is 3X3.
|
||||
static constexpr int32_t DIMENSION = 3;
|
||||
|
||||
Matrix3() = default;
|
||||
~Matrix3() = default;
|
||||
|
||||
void SetEntry(int32_t row, int32_t col, double value);
|
||||
|
||||
// Gets the inverse of this matrix;
|
||||
bool Invert(Matrix3& matrix) const;
|
||||
|
||||
inline Matrix3& operator*(double num)
|
||||
{
|
||||
for (auto& vector : matrix3X3_) {
|
||||
std::for_each(vector.begin(), vector.end(), [num](auto& item) { item = item * num; });
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix3N operator*(const Matrix3N& matrix) const;
|
||||
|
||||
// Make sure that the value of index is less than 3.
|
||||
inline std::vector<double>& operator[](int32_t index)
|
||||
{
|
||||
return matrix3X3_[index];
|
||||
}
|
||||
|
||||
// Make sure that the value of index is less than 3.
|
||||
inline const std::vector<double>& operator[](int32_t index) const
|
||||
{
|
||||
return matrix3X3_[index];
|
||||
}
|
||||
|
||||
// Make sure that the value of row is less than 3 and col is less than 3.
|
||||
inline double operator()(int32_t row, int32_t col) const
|
||||
{
|
||||
return matrix3X3_[row][col];
|
||||
}
|
||||
|
||||
Matrix3 Transpose() const;
|
||||
|
||||
// Make sure that the vector size is equal than column.
|
||||
std::vector<double> MapScalars(const std::vector<double>& src) const;
|
||||
|
||||
// Make sure that the vector size is equal than column.
|
||||
bool MapScalars(const std::vector<double>& src, std::vector<double>& result) const;
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::string val;
|
||||
for (auto& vector : matrix3X3_) {
|
||||
std::for_each(vector.begin(), vector.end(),
|
||||
[&val](auto& item) { val = val + "item: " + std::to_string(item) + " "; });
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::vector<double>> matrix3X3_ = { DIMENSION, std::vector<double>(DIMENSION, 0.0) };
|
||||
};
|
||||
|
||||
class ACE_EXPORT Matrix3N {
|
||||
public:
|
||||
// Matrix dimension is 3X3.
|
||||
static constexpr int32_t DIMENSION = 3;
|
||||
|
||||
explicit Matrix3N(int32_t columns);
|
||||
~Matrix3N() = default;
|
||||
|
||||
inline int32_t GetColNum() const
|
||||
{
|
||||
return columns_;
|
||||
}
|
||||
|
||||
bool SetEntry(int32_t row, int32_t col, double value);
|
||||
|
||||
inline Matrix3N& operator*(double num)
|
||||
{
|
||||
for (auto& vector : Matrix3n_) {
|
||||
std::for_each(vector.begin(), vector.end(), [num](auto& item) { item = item * num; });
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Make sure that the rows of MatrixN3 is equal than the columns of Matrix3N.
|
||||
Matrix3 operator*(const MatrixN3& matrix) const;
|
||||
|
||||
// Make sure that the value of index is less than 3.
|
||||
inline std::vector<double>& operator[](int32_t index)
|
||||
{
|
||||
return Matrix3n_[index];
|
||||
}
|
||||
|
||||
// Make sure that the value of index is less than 3.
|
||||
inline const std::vector<double>& operator[](int32_t index) const
|
||||
{
|
||||
return Matrix3n_[index];
|
||||
}
|
||||
|
||||
// Make sure that the value of row is less than 3 and col is less than columns.
|
||||
inline double operator()(int32_t row, int32_t col) const
|
||||
{
|
||||
return Matrix3n_[row][col];
|
||||
}
|
||||
|
||||
MatrixN3 Transpose() const;
|
||||
|
||||
// Make sure that the vector size is equal than column.
|
||||
std::vector<double> MapScalars(const std::vector<double>& src) const;
|
||||
|
||||
// Make sure that the vector size is equal than column.
|
||||
bool MapScalars(const std::vector<double>& src, std::vector<double>& result) const;
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::string val;
|
||||
for (auto& vector : Matrix3n_) {
|
||||
std::for_each(vector.begin(), vector.end(),
|
||||
[&val](auto& item) { val = val + "item: " + std::to_string(item) + " "; });
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::vector<double>> Matrix3n_;
|
||||
int32_t columns_ = 0;
|
||||
};
|
||||
|
||||
class ACE_EXPORT MatrixN3 {
|
||||
public:
|
||||
// Matrix dimension is 3XN.
|
||||
static constexpr int32_t DIMENSION = 3;
|
||||
|
||||
explicit MatrixN3(int32_t rows);
|
||||
~MatrixN3() = default;
|
||||
|
||||
inline int32_t GetRowNum() const
|
||||
{
|
||||
return rows_;
|
||||
}
|
||||
|
||||
bool SetEntry(int32_t row, int32_t col, double value);
|
||||
|
||||
inline MatrixN3& operator*(double num)
|
||||
{
|
||||
for (auto& vector : Matrixn3_) {
|
||||
std::for_each(vector.begin(), vector.end(), [num](auto& item) { item = item * num; });
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Make sure that the value of index is less than rows.
|
||||
inline std::vector<double>& operator[](int32_t index)
|
||||
{
|
||||
return Matrixn3_[index];
|
||||
}
|
||||
|
||||
// Make sure that the value of index is less than rows.
|
||||
inline const std::vector<double>& operator[](int32_t index) const
|
||||
{
|
||||
return Matrixn3_[index];
|
||||
}
|
||||
|
||||
// Make sure that the value of row is less than rows and col is less than 3.
|
||||
inline double operator()(int32_t row, int32_t col) const
|
||||
{
|
||||
return Matrixn3_[row][col];
|
||||
}
|
||||
|
||||
Matrix3N Transpose() const;
|
||||
|
||||
// Make sure that the vector size is equal than column.
|
||||
std::vector<double> MapScalars(const std::vector<double>& src) const;
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::string val;
|
||||
for (auto& vector : Matrixn3_) {
|
||||
std::for_each(vector.begin(), vector.end(),
|
||||
[&val](auto& item) { val = val + "item: " + std::to_string(item) + " "; });
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::vector<double>> Matrixn3_;
|
||||
int32_t rows_ = 0;
|
||||
};
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_MATRIX3_H
|
||||
@@ -22,11 +22,10 @@
|
||||
|
||||
namespace OHOS::Ace {
|
||||
namespace {
|
||||
|
||||
constexpr int32_t MATRIX_LENGTH = Matrix4::DIMENSION * Matrix4::DIMENSION;
|
||||
constexpr float ANGLE_UNIT = 0.017453f; // PI / 180
|
||||
constexpr double ANGLE_UNIT = 0.017453f; // PI / 180
|
||||
|
||||
inline bool IsEqual(const float& left, const float& right)
|
||||
inline bool IsEqual(const double& left, const double& right)
|
||||
{
|
||||
return NearEqual(left, right);
|
||||
}
|
||||
@@ -35,45 +34,33 @@ inline bool IsEqual(const float& left, const float& right)
|
||||
|
||||
Matrix4 Matrix4::CreateIdentity()
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::CreateTranslate(float x, float y, float z)
|
||||
Matrix4 Matrix4::CreateTranslate(double x, double y, double z)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::CreateScale(float x, float y, float z)
|
||||
Matrix4 Matrix4::CreateScale(double x, double y, double z)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::CreateRotate(float angle, float dx, float dy, float dz)
|
||||
Matrix4 Matrix4::CreateRotate(double angle, double dx, double dy, double dz)
|
||||
{
|
||||
// (x,y,z) need normalize
|
||||
float sum = dx * dx + dy * dy + dz * dz;
|
||||
double sum = dx * dx + dy * dy + dz * dz;
|
||||
if (NearZero(sum)) {
|
||||
return Matrix4::CreateIdentity();
|
||||
}
|
||||
|
||||
float x = dx / sqrt(sum);
|
||||
float y = dy / sqrt(sum);
|
||||
float z = dz / sqrt(sum);
|
||||
float redian = static_cast<float>(angle * (M_PI / 180.0f));
|
||||
float cosValue = cosf(redian);
|
||||
float sinValue = sinf(redian);
|
||||
double x = dx / sqrt(sum);
|
||||
double y = dy / sqrt(sum);
|
||||
double z = dz / sqrt(sum);
|
||||
double redian = static_cast<double>(angle * (M_PI / 180.0f));
|
||||
double cosValue = cosf(redian);
|
||||
double sinValue = sinf(redian);
|
||||
|
||||
return Matrix4(cosValue + (x * x * (1.0f - cosValue)), (x * y * (1.0f - cosValue)) - (z * sinValue),
|
||||
(x * z * (1.0f - cosValue)) + (y * sinValue), 0.0f, (y * x * (1.0f - cosValue)) + (z * sinValue),
|
||||
@@ -82,25 +69,18 @@ Matrix4 Matrix4::CreateRotate(float angle, float dx, float dy, float dz)
|
||||
cosValue + (z * z * (1.0f - cosValue)), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::CreateMatrix2D(float m00, float m10, float m01, float m11, float m03, float m13)
|
||||
Matrix4 Matrix4::CreateMatrix2D(double m00, double m10, double m01, double m11, double m03, double m13)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::CreateSkew(float x, float y)
|
||||
Matrix4 Matrix4::CreateSkew(double x, double y)
|
||||
{
|
||||
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, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
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,
|
||||
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::CreatePerspective(float distance)
|
||||
Matrix4 Matrix4::CreatePerspective(double distance)
|
||||
{
|
||||
auto result = CreateIdentity();
|
||||
if (GreatNotEqual(distance, 0.0f)) {
|
||||
@@ -112,10 +92,8 @@ Matrix4 Matrix4::CreatePerspective(float distance)
|
||||
Matrix4 Matrix4::Invert(const Matrix4& matrix)
|
||||
{
|
||||
Matrix4 inverted = CreateInvert(matrix);
|
||||
float determinant = matrix(0, 0) * inverted(0, 0) +
|
||||
matrix(0, 1) * inverted(1, 0) +
|
||||
matrix(0, 2) * inverted(2, 0) +
|
||||
matrix(0, 3) * inverted(3, 0);
|
||||
double determinant = matrix(0, 0) * inverted(0, 0) + matrix(0, 1) * inverted(1, 0) + matrix(0, 2) * inverted(2, 0) +
|
||||
matrix(0, 3) * inverted(3, 0);
|
||||
|
||||
if (!NearZero(determinant)) {
|
||||
inverted = inverted * (1.0f / determinant);
|
||||
@@ -135,8 +113,8 @@ Matrix4::Matrix4(const Matrix4& matrix)
|
||||
std::copy_n(&matrix.matrix4x4_[0][0], MATRIX_LENGTH, &matrix4x4_[0][0]);
|
||||
}
|
||||
|
||||
Matrix4::Matrix4(float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20,
|
||||
float m21, float m22, float m23, float m30, float m31, float m32, float m33)
|
||||
Matrix4::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)
|
||||
{
|
||||
matrix4x4_[0][0] = m00;
|
||||
matrix4x4_[1][0] = m01;
|
||||
@@ -156,7 +134,7 @@ Matrix4::Matrix4(float m00, float m01, float m02, float m03, float m10, float m1
|
||||
matrix4x4_[3][3] = m33;
|
||||
}
|
||||
|
||||
void Matrix4::SetScale(float x, float y, float z)
|
||||
void Matrix4::SetScale(double x, double y, double z)
|
||||
{
|
||||
// The 4X4 matrix scale index is [0][0], [1][1], [2][2], [3][3].
|
||||
matrix4x4_[0][0] = x;
|
||||
@@ -165,17 +143,17 @@ void Matrix4::SetScale(float x, float y, float z)
|
||||
matrix4x4_[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
float Matrix4::GetScaleX() const
|
||||
double Matrix4::GetScaleX() const
|
||||
{
|
||||
return matrix4x4_[0][0];
|
||||
}
|
||||
|
||||
float Matrix4::GetScaleY() const
|
||||
double Matrix4::GetScaleY() const
|
||||
{
|
||||
return matrix4x4_[1][1];
|
||||
}
|
||||
|
||||
void Matrix4::SetEntry(int32_t row, int32_t col, float value)
|
||||
void Matrix4::SetEntry(int32_t row, int32_t col, double value)
|
||||
{
|
||||
if ((row < 0 || row >= DIMENSION) || (col < 0 || col >= DIMENSION)) {
|
||||
return;
|
||||
@@ -188,7 +166,7 @@ bool Matrix4::IsIdentityMatrix() const
|
||||
return *this == CreateIdentity();
|
||||
}
|
||||
|
||||
void Matrix4::Rotate(float angle, float dx, float dy, float dz)
|
||||
void Matrix4::Rotate(double angle, double dx, double dy, double dz)
|
||||
{
|
||||
Matrix4 transform = *this;
|
||||
*this = transform * CreateRotate(angle, dx, dy, dz);
|
||||
@@ -257,10 +235,10 @@ bool Matrix4::operator==(const Matrix4& matrix) const
|
||||
return std::equal(&matrix4x4_[0][0], &matrix4x4_[0][0] + MATRIX_LENGTH, &matrix.matrix4x4_[0][0], IsEqual);
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::operator*(float num)
|
||||
Matrix4 Matrix4::operator*(double num)
|
||||
{
|
||||
Matrix4 ret(*this);
|
||||
std::for_each_n(&ret.matrix4x4_[0][0], MATRIX_LENGTH, [num](float& v) { v *= num; });
|
||||
std::for_each_n(&ret.matrix4x4_[0][0], MATRIX_LENGTH, [num](double& v) { v *= num; });
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -301,12 +279,28 @@ Matrix4 Matrix4::operator*(const Matrix4& matrix)
|
||||
matrix4x4_[3][3] * matrix(3, 3));
|
||||
}
|
||||
|
||||
Matrix4N Matrix4::operator*(const Matrix4N& matrix) const
|
||||
{
|
||||
int32_t columns = matrix.GetColNum();
|
||||
Matrix4N matrix4n { columns };
|
||||
for (auto i = 0; i < DIMENSION; i++) {
|
||||
for (auto j = 0; j < columns; j++) {
|
||||
double value = 0.0;
|
||||
for (auto k = 0; k < DIMENSION; k++) {
|
||||
value += matrix4x4_[i][k] * matrix[k][j];
|
||||
}
|
||||
matrix4n[i][j] = value;
|
||||
}
|
||||
}
|
||||
return matrix4n;
|
||||
}
|
||||
|
||||
Point Matrix4::operator*(const Point& point)
|
||||
{
|
||||
double x = point.GetX();
|
||||
double y = point.GetY();
|
||||
return Point(matrix4x4_[0][0] * x + matrix4x4_[1][0] * y + matrix4x4_[3][0],
|
||||
matrix4x4_[0][1] * x + matrix4x4_[1][1] * y + matrix4x4_[3][1]);
|
||||
matrix4x4_[0][1] * x + matrix4x4_[1][1] * y + matrix4x4_[3][1]);
|
||||
}
|
||||
|
||||
Matrix4& Matrix4::operator=(const Matrix4& matrix)
|
||||
@@ -318,7 +312,7 @@ Matrix4& Matrix4::operator=(const Matrix4& matrix)
|
||||
return *this;
|
||||
}
|
||||
|
||||
float Matrix4::operator[](int32_t index) const
|
||||
double Matrix4::operator[](int32_t index) const
|
||||
{
|
||||
if (index < 0 || index >= MATRIX_LENGTH) {
|
||||
return 0.0f;
|
||||
@@ -328,7 +322,7 @@ float Matrix4::operator[](int32_t index) const
|
||||
return matrix4x4_[row][col];
|
||||
}
|
||||
|
||||
float Matrix4::operator()(int32_t row, int32_t col) const
|
||||
double Matrix4::operator()(int32_t row, int32_t col) const
|
||||
{
|
||||
// Caller guarantee row and col in range of [0, 3].
|
||||
return matrix4x4_[row][col];
|
||||
@@ -383,14 +377,14 @@ void Matrix4::Transpose()
|
||||
std::swap(matrix4x4_[2][3], matrix4x4_[3][2]);
|
||||
}
|
||||
|
||||
void Matrix4::MapScalars(const float src[DIMENSION], float dst[DIMENSION]) const
|
||||
void Matrix4::MapScalars(const double src[DIMENSION], double dst[DIMENSION]) const
|
||||
{
|
||||
float storage[DIMENSION];
|
||||
double storage[DIMENSION];
|
||||
|
||||
float* result = (src == dst) ? storage : dst;
|
||||
double* result = (src == dst) ? storage : dst;
|
||||
|
||||
for (int i = 0; i < DIMENSION; i++) {
|
||||
float value = 0;
|
||||
double value = 0;
|
||||
for (int j = 0; j < DIMENSION; j++) {
|
||||
value += matrix4x4_[j][i] * src[j];
|
||||
}
|
||||
@@ -406,7 +400,7 @@ std::string Matrix4::ToString() const
|
||||
{
|
||||
std::string out;
|
||||
for (auto& i : matrix4x4_) {
|
||||
for (float j : i) {
|
||||
for (double j : i) {
|
||||
out += std::to_string(j);
|
||||
out += ",";
|
||||
}
|
||||
@@ -415,4 +409,119 @@ std::string Matrix4::ToString() const
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
Matrix4N::Matrix4N(int32_t columns) : columns_(columns)
|
||||
{
|
||||
matrix4n_.resize(DIMENSION, std::vector<double>(columns_, 0));
|
||||
}
|
||||
|
||||
bool Matrix4N::SetEntry(int32_t row, int32_t col, double value)
|
||||
{
|
||||
if (row >= DIMENSION || col >= columns_) {
|
||||
return false;
|
||||
}
|
||||
matrix4n_[row][col] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
Matrix4 Matrix4N::operator*(const MatrixN4& matrix) const
|
||||
{
|
||||
auto matrix4 = Matrix4::CreateIdentity();
|
||||
if (columns_ != matrix.GetRowNum()) {
|
||||
return matrix4;
|
||||
}
|
||||
for (auto i = 0; i < DIMENSION; i++) {
|
||||
for (auto j = 0; j < DIMENSION; j++) {
|
||||
double value = 0.0;
|
||||
for (auto k = 0; k < columns_; k++) {
|
||||
value += matrix4n_[i][k] * matrix[k][j];
|
||||
}
|
||||
matrix4.SetEntry(i, j, value);
|
||||
}
|
||||
}
|
||||
return matrix4;
|
||||
}
|
||||
|
||||
MatrixN4 Matrix4N::Transpose() const
|
||||
{
|
||||
MatrixN4 matrix { columns_ };
|
||||
for (auto i = 0; i < DIMENSION; i++) {
|
||||
for (auto j = 0; j < columns_; j++) {
|
||||
matrix[j][i] = matrix4n_[i][j];
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
std::vector<double> Matrix4N::MapScalars(const std::vector<double>& src) const
|
||||
{
|
||||
std::vector<double> value { DIMENSION, 0 };
|
||||
if (static_cast<int32_t>(src.size()) != columns_) {
|
||||
return value;
|
||||
}
|
||||
for (int32_t i = 0; i < DIMENSION; i++) {
|
||||
double item = 0.0;
|
||||
for (int32_t j = 0; j < columns_; j++) {
|
||||
item = item + matrix4n_[i][j] * src[j];
|
||||
}
|
||||
value[i] = item;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool Matrix4N::MapScalars(const std::vector<double>& src, std::vector<double>& result) const
|
||||
{
|
||||
if (static_cast<int32_t>(src.size()) != columns_) {
|
||||
return false;
|
||||
}
|
||||
result.resize(DIMENSION, 0);
|
||||
for (int32_t i = 0; i < DIMENSION; i++) {
|
||||
double item = 0.0;
|
||||
for (int32_t j = 0; j < columns_; j++) {
|
||||
item = item + matrix4n_[i][j] * src[j];
|
||||
}
|
||||
result[i] = item;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MatrixN4::MatrixN4(int32_t rows) : rows_(rows)
|
||||
{
|
||||
matrixn4_.resize(rows, std::vector<double>(DIMENSION, 0));
|
||||
}
|
||||
|
||||
bool MatrixN4::SetEntry(int32_t row, int32_t col, double value)
|
||||
{
|
||||
if (row >= rows_ || col >= DIMENSION) {
|
||||
return false;
|
||||
}
|
||||
matrixn4_[row][col] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
Matrix4N MatrixN4::Transpose() const
|
||||
{
|
||||
Matrix4N matrix { rows_ };
|
||||
for (auto i = 0; i < DIMENSION; i++) {
|
||||
for (auto j = 0; j < rows_; j++) {
|
||||
matrix[i][j] = matrixn4_[j][i];
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
std::vector<double> MatrixN4::MapScalars(const std::vector<double>& src) const
|
||||
{
|
||||
std::vector<double> value { rows_, 0 };
|
||||
if (static_cast<int32_t>(src.size()) != DIMENSION) {
|
||||
return value;
|
||||
}
|
||||
for (int32_t i = 0; i < rows_; i++) {
|
||||
double item = 0.0;
|
||||
for (int32_t j = 0; j < DIMENSION; j++) {
|
||||
item = item + matrixn4_[i][j] * src[j];
|
||||
}
|
||||
value[i] = item;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
@@ -16,10 +16,15 @@
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_MATRIX4_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_MATRIX4_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/geometry/point.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
class Matrix4N;
|
||||
class MatrixN4;
|
||||
|
||||
class ACE_EXPORT Matrix4 {
|
||||
public:
|
||||
// Matrix dimension is 4X4.
|
||||
@@ -27,51 +32,54 @@ public:
|
||||
// Create an identity matrix.
|
||||
static Matrix4 CreateIdentity();
|
||||
// Multiplies this matrix by another that translates coordinates by the vector (x, y, z).
|
||||
static Matrix4 CreateTranslate(float x, float y, float z);
|
||||
static Matrix4 CreateTranslate(double x, double y, double z);
|
||||
// Multiplies this matrix by another that scales coordinates by the vector (x, y, z).
|
||||
static Matrix4 CreateScale(float x, float y, float z);
|
||||
static Matrix4 CreateScale(double x, double y, double z);
|
||||
// Multiplies this matrix by another that rotates coordinates through angle degrees about the vector (dx, dy, dz).
|
||||
static Matrix4 CreateRotate(float angle, float dx, float dy, float dz);
|
||||
static Matrix4 CreateRotate(double angle, double dx, double dy, double dz);
|
||||
|
||||
static Matrix4 CreateMatrix2D(float m00, float m10, float m01, float m11, float m03, float m13);
|
||||
static Matrix4 CreateMatrix2D(double m00, double m10, double m01, double m11, double m03, double m13);
|
||||
// Multiplies this matrix by another that skew through angle degrees.
|
||||
static Matrix4 CreateSkew(float x, float y);
|
||||
static Matrix4 CreateSkew(double x, double y);
|
||||
// Create an perspective matrix, the distance value represents the distance between the user and the z=0 plane. not
|
||||
// support percent
|
||||
static Matrix4 CreatePerspective(float distance);
|
||||
static Matrix4 CreatePerspective(double distance);
|
||||
// Returns the inverse of this matrix. Returns the identity if this matrix cannot be inverted;
|
||||
static Matrix4 Invert(const Matrix4& matrix);
|
||||
|
||||
Matrix4();
|
||||
Matrix4(const Matrix4& matrix);
|
||||
Matrix4(
|
||||
float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33);
|
||||
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);
|
||||
~Matrix4() = default;
|
||||
void SetScale(float x, float y, float z);
|
||||
float GetScaleX() const;
|
||||
float GetScaleY() const;
|
||||
void Rotate(float angle, float dx, float dy, float dz);
|
||||
void SetEntry(int32_t row, int32_t col, float value);
|
||||
void SetScale(double x, double y, double z);
|
||||
double GetScaleX() const;
|
||||
double GetScaleY() const;
|
||||
void Rotate(double angle, double dx, double dy, double dz);
|
||||
void SetEntry(int32_t row, int32_t col, double value);
|
||||
bool IsIdentityMatrix() const;
|
||||
int32_t Count() const;
|
||||
|
||||
bool operator==(const Matrix4& matrix) const;
|
||||
Matrix4 operator*(float num);
|
||||
Matrix4 operator*(double num);
|
||||
Matrix4 operator*(const Matrix4& matrix);
|
||||
|
||||
Matrix4N operator*(const Matrix4N& matrix) const;
|
||||
|
||||
// Transform point by the matrix
|
||||
Point operator*(const Point& point);
|
||||
Matrix4& operator=(const Matrix4& matrix);
|
||||
float operator[](int32_t index) const;
|
||||
inline float Get(int32_t row, int32_t col) const
|
||||
double operator[](int32_t index) const;
|
||||
inline double Get(int32_t row, int32_t col) const
|
||||
{
|
||||
ACE_DCHECK((unsigned)row < DIMENSION);
|
||||
ACE_DCHECK((unsigned)col < DIMENSION);
|
||||
return matrix4x4_[col][row];
|
||||
}
|
||||
inline void Set(int32_t row, int32_t col, float value)
|
||||
inline void Set(int32_t row, int32_t col, double value)
|
||||
{
|
||||
ACE_DCHECK((unsigned)row < DIMENSION);
|
||||
ACE_DCHECK((unsigned)col < DIMENSION);
|
||||
@@ -79,8 +87,8 @@ public:
|
||||
}
|
||||
double Determinant() const;
|
||||
void Transpose();
|
||||
void MapScalars(const float src[DIMENSION], float dst[DIMENSION]) const;
|
||||
inline void MapScalars(float vec[DIMENSION], int length = DIMENSION) const
|
||||
void MapScalars(const double src[DIMENSION], double dst[DIMENSION]) const;
|
||||
inline void MapScalars(double vec[DIMENSION], int length = DIMENSION) const
|
||||
{
|
||||
if (length == DIMENSION) {
|
||||
this->MapScalars(vec, vec);
|
||||
@@ -90,9 +98,9 @@ public:
|
||||
|
||||
private:
|
||||
static Matrix4 CreateInvert(const Matrix4& matrix);
|
||||
float operator()(int32_t row, int32_t col) const;
|
||||
double operator()(int32_t row, int32_t col) const;
|
||||
|
||||
float matrix4x4_[DIMENSION][DIMENSION] = {
|
||||
double matrix4x4_[DIMENSION][DIMENSION] = {
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
@@ -100,6 +108,114 @@ private:
|
||||
};
|
||||
};
|
||||
|
||||
class ACE_EXPORT Matrix4N {
|
||||
public:
|
||||
// Matrix dimension is 4X4.
|
||||
static constexpr int32_t DIMENSION = 4;
|
||||
|
||||
explicit Matrix4N(int32_t columns);
|
||||
~Matrix4N() = default;
|
||||
|
||||
inline int32_t GetColNum() const
|
||||
{
|
||||
return columns_;
|
||||
}
|
||||
|
||||
bool SetEntry(int32_t row, int32_t col, double value);
|
||||
|
||||
inline Matrix4N& operator*(double num)
|
||||
{
|
||||
for (auto& vector : matrix4n_) {
|
||||
std::for_each(vector.begin(), vector.end(), [num](auto& item) { item = item * num; });
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Make sure that the rows of matrixN4 is equal than the columns of matrix4N.
|
||||
Matrix4 operator*(const MatrixN4& matrix) const;
|
||||
|
||||
// Make sure that the value of index is less than 4.
|
||||
inline std::vector<double>& operator[](int32_t index)
|
||||
{
|
||||
return matrix4n_[index];
|
||||
}
|
||||
|
||||
// Make sure that the value of index is less than 4.
|
||||
inline const std::vector<double>& operator[](int32_t index) const
|
||||
{
|
||||
return matrix4n_[index];
|
||||
}
|
||||
|
||||
// Make sure that the value of row is less than 4 and col is less than columns.
|
||||
inline double operator()(int32_t row, int32_t col) const
|
||||
{
|
||||
return matrix4n_[row][col];
|
||||
}
|
||||
|
||||
MatrixN4 Transpose() const;
|
||||
|
||||
// Make sure that the vector size is equal than column.
|
||||
std::vector<double> MapScalars(const std::vector<double>& src) const;
|
||||
|
||||
// Make sure that the vector size is equal than column.
|
||||
bool MapScalars(const std::vector<double>& src, std::vector<double>& result) const;
|
||||
|
||||
private:
|
||||
std::vector<std::vector<double>> matrix4n_;
|
||||
int32_t columns_ = 0;
|
||||
};
|
||||
|
||||
class ACE_EXPORT MatrixN4 {
|
||||
public:
|
||||
// Matrix dimension is 4XN.
|
||||
static constexpr int32_t DIMENSION = 4;
|
||||
|
||||
explicit MatrixN4(int32_t rows);
|
||||
~MatrixN4() = default;
|
||||
|
||||
inline int32_t GetRowNum() const
|
||||
{
|
||||
return rows_;
|
||||
}
|
||||
|
||||
bool SetEntry(int32_t row, int32_t col, double value);
|
||||
|
||||
inline MatrixN4& operator*(double num)
|
||||
{
|
||||
for (auto& vector : matrixn4_) {
|
||||
std::for_each(vector.begin(), vector.end(), [num](auto& item) { item = item * num; });
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Make sure that the value of index is less than rows.
|
||||
inline std::vector<double>& operator[](int32_t index)
|
||||
{
|
||||
return matrixn4_[index];
|
||||
}
|
||||
|
||||
// Make sure that the value of index is less than rows.
|
||||
inline const std::vector<double>& operator[](int32_t index) const
|
||||
{
|
||||
return matrixn4_[index];
|
||||
}
|
||||
|
||||
// Make sure that the value of row is less than rows and col is less than 4.
|
||||
inline double operator()(int32_t row, int32_t col) const
|
||||
{
|
||||
return matrixn4_[row][col];
|
||||
}
|
||||
|
||||
Matrix4N Transpose() const;
|
||||
|
||||
// Make sure that the vector size is equal than column.
|
||||
std::vector<double> MapScalars(const std::vector<double>& src) const;
|
||||
|
||||
private:
|
||||
std::vector<std::vector<double>> matrixn4_;
|
||||
int32_t rows_ = 0;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_MATRIX4_H
|
||||
|
||||
@@ -499,7 +499,7 @@ bool TransformUtil::DecomposeTransform(DecomposedTransform& out, const Matrix4&
|
||||
}
|
||||
|
||||
if (!NearZero(matrix.Get(3, 0)) || !NearZero(matrix.Get(3, 1)) || !NearZero(matrix.Get(3, 2))) {
|
||||
float rhs[4] = { matrix.Get(3, 0), matrix.Get(3, 1), matrix.Get(3, 2), matrix.Get(3, 3) };
|
||||
double rhs[4] = { matrix.Get(3, 0), matrix.Get(3, 1), matrix.Get(3, 2), matrix.Get(3, 3) };
|
||||
|
||||
Matrix4 inversePerspectiveMatrix = Matrix4::Invert(perspectiveMatrix);
|
||||
Matrix4 transposedInversePerspectiveMatrix = inversePerspectiveMatrix;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
// nano seconds.
|
||||
using TimeStamp = std::chrono::high_resolution_clock::time_point;
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
@@ -74,6 +74,7 @@ struct TouchEvent final {
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
TouchType type = TouchType::UNKNOWN;
|
||||
// nanosecond time stamp.
|
||||
TimeStamp time;
|
||||
double size = 0.0;
|
||||
float force = 0.0f;
|
||||
|
||||
@@ -163,6 +163,7 @@ void DragRecognizer::HandleTouchUpEvent(const TouchEvent& event)
|
||||
}
|
||||
|
||||
auto& dragInfo = iter->second;
|
||||
dragInfo.velocityTracker_.UpdateTouchPoint(event, true);
|
||||
if (dragInfo.states_ == DetectState::DETECTED) {
|
||||
bool upSuccess = true;
|
||||
for (auto entry = dragFingers_.begin(); entry != dragFingers_.end(); ++entry) {
|
||||
|
||||
@@ -19,27 +19,55 @@
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
void VelocityTracker::UpdateTouchPoint(const TouchEvent& event)
|
||||
void VelocityTracker::UpdateTouchPoint(const TouchEvent& event, bool end)
|
||||
{
|
||||
isVelocityDone_ = false;
|
||||
currentTrackPoint_ = event;
|
||||
if (isFirstPoint_) {
|
||||
firstTrackPoint_ = event;
|
||||
lastPosition_ = event.GetOffset();
|
||||
lastTimePoint_ = event.time;
|
||||
isFirstPoint_ = false;
|
||||
} else {
|
||||
delta_ = event.GetOffset() - lastPosition_;
|
||||
lastPosition_ = event.GetOffset();
|
||||
}
|
||||
std::chrono::duration<double> diffTime = event.time - lastTimePoint_;
|
||||
lastTimePoint_ = event.time;
|
||||
lastPosition_ = event.GetOffset();
|
||||
// judge duration is 500ms.
|
||||
static const double range = 0.5;
|
||||
if (delta_.IsZero() && end && (diffTime.count() < range)) {
|
||||
return;
|
||||
}
|
||||
|
||||
delta_ = event.GetOffset() - lastPosition_;
|
||||
|
||||
// nanoseconds duration to seconds.
|
||||
const std::chrono::duration<double> duration = event.time - lastTimePoint_;
|
||||
if (!NearZero(duration.count())) {
|
||||
velocity_.SetOffsetPerSecond(delta_ / duration.count());
|
||||
std::chrono::duration<double> duration = event.time - firstTrackPoint_.time;
|
||||
auto seconds = duration.count();
|
||||
xAxis_.UpdatePoint(seconds, event.x);
|
||||
yAxis_.UpdatePoint(seconds, event.y);
|
||||
}
|
||||
|
||||
void VelocityTracker::UpdateVelocity()
|
||||
{
|
||||
if (isVelocityDone_) {
|
||||
return;
|
||||
}
|
||||
// the least square method three params curve is 0 * x^3 + a2 * x^2 + a1 * x + a0
|
||||
// the velocity is 2 * a2 * x + a1;
|
||||
static const int32_t linearParam = 2;
|
||||
std::vector<double> xAxis { 3, 0 };
|
||||
auto xValue = xAxis_.GetXVals().back();
|
||||
double xVelocity = 0.0;
|
||||
if (xAxis_.GetLeastSquareParams(xAxis)) {
|
||||
xVelocity = linearParam * xAxis[0] * xValue + xAxis[1];
|
||||
}
|
||||
std::vector<double> yAxis { 3, 0 };
|
||||
auto yValue = yAxis_.GetXVals().back();
|
||||
double yVelocity = 0.0;
|
||||
if (yAxis_.GetLeastSquareParams(yAxis)) {
|
||||
yVelocity = linearParam * yAxis[0] * yValue + yAxis[1];
|
||||
}
|
||||
|
||||
lastPosition_ = event.GetOffset();
|
||||
lastTimePoint_ = event.time;
|
||||
velocity_.SetOffsetPerSecond({ xVelocity, yVelocity });
|
||||
isVelocityDone_ = true;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_GESTURES_VELOCITY_TRACKER_H
|
||||
|
||||
#include "base/geometry/axis.h"
|
||||
#include "base/geometry/least_square_impl.h"
|
||||
#include "base/geometry/offset.h"
|
||||
#include "core/event/touch_event.h"
|
||||
#include "core/gestures/velocity.h"
|
||||
@@ -35,9 +36,11 @@ public:
|
||||
velocity_.Reset();
|
||||
delta_.Reset();
|
||||
isFirstPoint_ = true;
|
||||
xAxis_.Reset();
|
||||
yAxis_.Reset();
|
||||
}
|
||||
|
||||
void UpdateTouchPoint(const TouchEvent& event);
|
||||
void UpdateTouchPoint(const TouchEvent& event, bool end = false);
|
||||
|
||||
const TouchEvent& GetFirstTrackPoint() const
|
||||
{
|
||||
@@ -59,8 +62,9 @@ public:
|
||||
return delta_;
|
||||
}
|
||||
|
||||
const Velocity& GetVelocity() const
|
||||
const Velocity& GetVelocity()
|
||||
{
|
||||
UpdateVelocity();
|
||||
return velocity_;
|
||||
}
|
||||
|
||||
@@ -74,7 +78,7 @@ public:
|
||||
case Axis::VERTICAL:
|
||||
return lastPosition_.GetY();
|
||||
default:
|
||||
return 0.0;
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,12 +92,13 @@ public:
|
||||
case Axis::VERTICAL:
|
||||
return delta_.GetY();
|
||||
default:
|
||||
return 0.0;
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
double GetMainAxisVelocity() const
|
||||
double GetMainAxisVelocity()
|
||||
{
|
||||
UpdateVelocity();
|
||||
switch (mainAxis_) {
|
||||
case Axis::FREE:
|
||||
return velocity_.GetVelocityValue();
|
||||
@@ -102,11 +107,13 @@ public:
|
||||
case Axis::VERTICAL:
|
||||
return velocity_.GetVelocityY();
|
||||
default:
|
||||
return 0.0;
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void UpdateVelocity();
|
||||
|
||||
Axis mainAxis_ { Axis::FREE };
|
||||
TouchEvent firstTrackPoint_;
|
||||
TouchEvent currentTrackPoint_;
|
||||
@@ -115,6 +122,9 @@ private:
|
||||
Offset delta_;
|
||||
bool isFirstPoint_ = true;
|
||||
TimeStamp lastTimePoint_;
|
||||
LeastSquareImpl xAxis_ { 3, 5 };
|
||||
LeastSquareImpl yAxis_ { 3, 5 };
|
||||
bool isVelocityDone_ = false;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
@@ -43,6 +43,8 @@ ohos_unittest("PipelineContextTest") {
|
||||
"$ace_root/adapter/ohos/osal/log_wrapper.cpp",
|
||||
"$ace_root/frameworks/base/geometry/animatable_dimension.cpp",
|
||||
"$ace_root/frameworks/base/geometry/animatable_matrix4.cpp",
|
||||
"$ace_root/frameworks/base/geometry/least_square_impl.cpp",
|
||||
"$ace_root/frameworks/base/geometry/matrix3.cpp",
|
||||
"$ace_root/frameworks/base/geometry/matrix4.cpp",
|
||||
"$ace_root/frameworks/base/geometry/quaternion.cpp",
|
||||
"$ace_root/frameworks/base/geometry/transform_util.cpp",
|
||||
|
||||
Reference in New Issue
Block a user