1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#ifndef OHOS_ROSEN_WM_MATH_H 17#define OHOS_ROSEN_WM_MATH_H 18 19#include <cmath> 20#include <limits> 21 22namespace OHOS::Rosen { 23namespace MathHelper { 24constexpr float PI = 3.14159265f; 25constexpr float INF = std::numeric_limits<float>::infinity(); 26constexpr float NAG_INF = -std::numeric_limits<float>::infinity(); 27constexpr float POS_ZERO = 0.001f; 28constexpr float NAG_ZERO = -POS_ZERO; 29inline bool NearZero(float val) 30{ 31 return val < POS_ZERO && val > NAG_ZERO; 32} 33 34inline float ToRadians(float degrees) 35{ 36 return degrees * PI / 180.0f; 37} 38 39inline float ToDegrees(float radians) 40{ 41 return radians * 180.0f / PI; 42} 43 44inline bool LessNotEqual(double left, double right) 45{ 46 static constexpr double eps = -0.001f; 47 return (left - right) < eps; 48} 49 50inline bool GreatNotEqual(double left, double right) 51{ 52 static constexpr double eps = 0.001f; 53 return (left - right) > eps; 54} 55 56template <typename T> 57T Max(const T& a, const T& b) 58{ 59 return (a < b ? b : a); 60} 61 62template <typename T, typename... Ts> 63T Max(const T& a, const Ts&... bs) 64{ 65 return Max(a, Max(bs...)); 66} 67 68template <typename T> 69T Min(const T& a, const T& b) 70{ 71 return (a < b ? a : b); 72} 73 74template <typename T, typename... Ts> 75T Min(const T& a, const Ts&... bs) 76{ 77 return Min(a, Min(bs...)); 78} 79 80template <typename T> 81T Clamp(const T& value, const T& lower, const T& upper) 82{ 83 return Min(upper, Max(lower, value)); 84} 85} // namespace MathHelper 86 87namespace TransformHelper { 88struct Vector2 { 89 float x_, y_; 90 Vector2() : x_(0.0f), y_(0.0f) {} 91 Vector2(float inX, float inY) 92 : x_(inX), y_(inY) {} 93 friend Vector2 operator-(const Vector2& v) 94 { 95 return Vector2 { -v.x_, -v.y_ }; 96 } 97 friend Vector2 operator+(const Vector2& a, const Vector2& b) 98 { 99 return Vector2 { a.x_ + b.x_, a.y_ + b.y_ }; 100 } 101 friend Vector2 operator-(const Vector2& a, const Vector2& b) 102 { 103 return Vector2 { a.x_ - b.x_, a.y_ - b.y_ }; 104 } 105 float LengthSq() const 106 { 107 return (x_ * x_ + y_ * y_); 108 } 109 float Length() const 110 { 111 return (std::sqrt(LengthSq())); 112 } 113}; 114 115struct Vector3 { 116 float x_, y_, z_; 117 Vector3() : x_(0.0f), y_(0.0f), z_(0.0f) {} 118 Vector3(float inX, float inY, float inZ) 119 : x_(inX), y_(inY), z_(inZ) {} 120 friend Vector3 operator-(const Vector3& v) 121 { 122 return Vector3 { -v.x_, -v.y_, -v.z_ }; 123 } 124 friend Vector3 operator+(const Vector3& a, const Vector3& b) 125 { 126 return Vector3 { a.x_ + b.x_, a.y_ + b.y_, a.z_ + b.z_ }; 127 } 128 friend Vector3 operator-(const Vector3& a, const Vector3& b) 129 { 130 return Vector3 { a.x_ - b.x_, a.y_ - b.y_, a.z_ - b.z_ }; 131 } 132 // Scalar multiplication 133 friend Vector3 operator*(const Vector3& vec, float scalar) 134 { 135 return Vector3(vec.x_ * scalar, vec.y_ * scalar, vec.z_ * scalar); 136 } 137 // Scalar multiplication 138 friend Vector3 operator*(float scalar, const Vector3& vec) 139 { 140 return Vector3(vec.x_ * scalar, vec.y_ * scalar, vec.z_ * scalar); 141 } 142 // Scalar *= 143 Vector3& operator*=(float scalar) 144 { 145 x_ *= scalar; 146 y_ *= scalar; 147 z_ *= scalar; 148 return *this; 149 } 150 float LengthSq() const 151 { 152 return (x_ * x_ + y_ * y_ + z_ * z_); 153 } 154 float Length() const 155 { 156 return (std::sqrt(LengthSq())); 157 } 158 void Normalize() 159 { 160 float length = Length(); 161 if (length > MathHelper::POS_ZERO) { 162 x_ /= length; 163 y_ /= length; 164 z_ /= length; 165 } 166 } 167 static Vector3 Normalize(const Vector3& vec) 168 { 169 Vector3 temp = vec; 170 temp.Normalize(); 171 return temp; 172 } 173 static float Dot(const Vector3& a, const Vector3& b) 174 { 175 return (a.x_ * b.x_ + a.y_ * b.y_ + a.z_ * b.z_); 176 } 177 static Vector3 Cross(const Vector3& a, const Vector3& b) 178 { 179 Vector3 temp; 180 temp.x_ = a.y_ * b.z_ - a.z_ * b.y_; 181 temp.y_ = a.z_ * b.x_ - a.x_ * b.z_; 182 temp.z_ = a.x_ * b.y_ - a.y_ * b.x_; 183 return temp; 184 } 185}; 186 187struct Matrix3 { 188 float mat_[3][3]; 189 190 friend Matrix3 operator*(const Matrix3& left, const Matrix3& right); 191 Matrix3& operator*=(const Matrix3& right); 192 static const Matrix3 Identity; 193}; 194 195struct Matrix4 { 196 float mat_[4][4]; 197 198 friend Matrix4 operator*(const Matrix4& left, const Matrix4& right); 199 Matrix4& operator*=(const Matrix4& right); 200 void SwapRow(int row1, int row2); 201 // Inverse matrix with Gauss-Jordan method 202 void Invert(); 203 // Extract the scale component from the matrix 204 Vector3 GetScale() const; 205 // Get the translation component of the matrix 206 Vector3 GetTranslation() const; 207 static const Matrix4 Identity; 208 static constexpr int MAT_SIZE = 4; 209}; 210 211// Create a scale matrix with x and y scales(in xy-plane) 212Matrix3 CreateScale(float xScale, float yScale); 213// Create a rotation matrix about the Z axis 214// theta is in radians 215Matrix3 CreateRotation(float theta); 216// Create a translation matrix (on the xy-plane) 217Matrix3 CreateTranslation(const Vector2& trans); 218// Create a scale matrix with x, y, and z scales 219Matrix4 CreateScale(float xScale, float yScale, float zScale); 220// Create a rotation matrix about X axis 221// theta is in radians 222Matrix4 CreateRotationX(float theta); 223// Create a rotation matrix about Y axis 224// theta is in radians 225Matrix4 CreateRotationY(float theta); 226// Create a rotation matrix about Z axis 227// theta is in radians 228Matrix4 CreateRotationZ(float theta); 229// Create a 3D translation matrix 230Matrix4 CreateTranslation(const Vector3& trans); 231Matrix4 CreateLookAt(const Vector3& eye, const Vector3& target, const Vector3& up); 232Matrix4 CreatePerspective(const Vector3& camera); 233// Transform a Vector2 in xy-plane by matrix3 234Vector2 Transform(const Vector2& vec, const Matrix3& mat); 235// Transform a Vector3 in 3D world by matrix4 236Vector3 Transform(const Vector3& vec, const Matrix4& mat); 237// Transform the vector and renormalize the w component 238Vector3 TransformWithPerspDiv(const Vector3& vec, const Matrix4& mat, float w = 1.0f); 239// Given a screen point, unprojects it into origin position at screen, 240// based on the current transform matrix 241Vector2 GetOriginScreenPoint(const Vector2& p, const Matrix4& mat); 242} // namespace TransformHelper 243} // namespace OHOS::Rosen 244#endif // OHOS_ROSEN_WM_MATH_H