• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
22 namespace OHOS::Rosen {
23 namespace MathHelper {
24 constexpr float PI = 3.14159265f;
25 constexpr float INF = std::numeric_limits<float>::infinity();
26 constexpr float NAG_INF = -std::numeric_limits<float>::infinity();
27 constexpr float POS_ZERO = 0.001f;
28 constexpr float NAG_ZERO = -POS_ZERO;
NearZero(float val)29 inline bool NearZero(float val)
30 {
31     return val < POS_ZERO && val > NAG_ZERO;
32 }
33 
NearEqual(float left,float right)34 inline bool NearEqual(float left, float right) { return std::abs(left - right) < POS_ZERO; }
35 
ToRadians(float degrees)36 inline float ToRadians(float degrees)
37 {
38     return degrees * PI / 180.0f;
39 }
40 
ToDegrees(float radians)41 inline float ToDegrees(float radians)
42 {
43     return radians * 180.0f / PI;
44 }
45 
LessNotEqual(double left,double right)46 inline bool LessNotEqual(double left, double right)
47 {
48     static constexpr double eps = -0.001f;
49     return (left - right) < eps;
50 }
51 
GreatNotEqual(double left,double right)52 inline bool GreatNotEqual(double left, double right)
53 {
54     static constexpr double eps = 0.001f;
55     return (left - right) > eps;
56 }
57 
58 template <typename T>
Max(const T & a,const T & b)59 T Max(const T& a, const T& b)
60 {
61     return (a < b ? b : a);
62 }
63 
64 template <typename T, typename... Ts>
Max(const T & a,const Ts &...bs)65 T Max(const T& a, const Ts&... bs)
66 {
67     return Max(a, Max(bs...));
68 }
69 
70 template <typename T>
Min(const T & a,const T & b)71 T Min(const T& a, const T& b)
72 {
73     return (a < b ? a : b);
74 }
75 
76 template <typename T, typename... Ts>
Min(const T & a,const Ts &...bs)77 T Min(const T& a, const Ts&... bs)
78 {
79     return Min(a, Min(bs...));
80 }
81 
82 template <typename T>
Clamp(const T & value,const T & lower,const T & upper)83 T Clamp(const T& value, const T& lower, const T& upper)
84 {
85     return Min(upper, Max(lower, value));
86 }
87 } // namespace MathHelper
88 
89 namespace TransformHelper {
90 struct Vector2 {
91     float x_, y_;
Vector2Vector292     Vector2() : x_(0.0f), y_(0.0f) {}
Vector2Vector293     Vector2(float inX, float inY)
94         : x_(inX), y_(inY) {}
95     friend Vector2 operator-(const Vector2& v)
96     {
97         return Vector2 { -v.x_, -v.y_ };
98     }
99     friend Vector2 operator+(const Vector2& a, const Vector2& b)
100     {
101         return Vector2 { a.x_ + b.x_, a.y_ + b.y_ };
102     }
103     friend Vector2 operator-(const Vector2& a, const Vector2& b)
104     {
105         return Vector2 { a.x_ - b.x_, a.y_ - b.y_ };
106     }
LengthSqVector2107     float LengthSq() const
108     {
109         return (x_ * x_ + y_ * y_);
110     }
LengthVector2111     float Length() const
112     {
113         return (std::sqrt(LengthSq()));
114     }
115 };
116 
117 struct Vector3 {
118     float x_, y_, z_;
Vector3Vector3119     Vector3() : x_(0.0f), y_(0.0f), z_(0.0f) {}
Vector3Vector3120     Vector3(float inX, float inY, float inZ)
121         : x_(inX), y_(inY), z_(inZ) {}
122     friend Vector3 operator-(const Vector3& v)
123     {
124         return Vector3 { -v.x_, -v.y_, -v.z_ };
125     }
126     friend Vector3 operator+(const Vector3& a, const Vector3& b)
127     {
128         return Vector3 { a.x_ + b.x_, a.y_ + b.y_, a.z_ + b.z_ };
129     }
130     friend Vector3 operator-(const Vector3& a, const Vector3& b)
131     {
132         return Vector3 { a.x_ - b.x_, a.y_ - b.y_, a.z_ - b.z_ };
133     }
134     // Scalar multiplication
135     friend Vector3 operator*(const Vector3& vec, float scalar)
136     {
137         return Vector3(vec.x_ * scalar, vec.y_ * scalar, vec.z_ * scalar);
138     }
139     // Scalar multiplication
140     friend Vector3 operator*(float scalar, const Vector3& vec)
141     {
142         return Vector3(vec.x_ * scalar, vec.y_ * scalar, vec.z_ * scalar);
143     }
144     // Scalar *=
145     Vector3& operator*=(float scalar)
146     {
147         x_ *= scalar;
148         y_ *= scalar;
149         z_ *= scalar;
150         return *this;
151     }
LengthSqVector3152     float LengthSq() const
153     {
154         return (x_ * x_ + y_ * y_ + z_ * z_);
155     }
LengthVector3156     float Length() const
157     {
158         return (std::sqrt(LengthSq()));
159     }
NormalizeVector3160     void Normalize()
161     {
162         float length = Length();
163         if (length > MathHelper::POS_ZERO) {
164             x_ /= length;
165             y_ /= length;
166             z_ /= length;
167         }
168     }
NormalizeVector3169     static Vector3 Normalize(const Vector3& vec)
170     {
171         Vector3 temp = vec;
172         temp.Normalize();
173         return temp;
174     }
DotVector3175     static float Dot(const Vector3& a, const Vector3& b)
176     {
177         return (a.x_ * b.x_ + a.y_ * b.y_ + a.z_ * b.z_);
178     }
CrossVector3179     static Vector3 Cross(const Vector3& a, const Vector3& b)
180     {
181         Vector3 temp;
182         temp.x_ = a.y_ * b.z_ - a.z_ * b.y_;
183         temp.y_ = a.z_ * b.x_ - a.x_ * b.z_;
184         temp.z_ = a.x_ * b.y_ - a.y_ * b.x_;
185         return temp;
186     }
187 };
188 
189 struct Matrix3 {
190     float mat_[3][3];
191 
192     friend Matrix3 operator*(const Matrix3& left, const Matrix3& right);
193     Matrix3& operator*=(const Matrix3& right);
194     static const Matrix3 Identity;
195 };
196 
197 struct Matrix4 {
198     float mat_[4][4];
199 
200     friend Matrix4 operator*(const Matrix4& left, const Matrix4& right);
201     Matrix4& operator*=(const Matrix4& right);
202     void SwapRow(int row1, int row2);
203     // Inverse matrix with Gauss-Jordan method
204     void Invert();
205     // Extract the scale component from the matrix
206     Vector3 GetScale() const;
207     // Get the translation component of the matrix
208     Vector3 GetTranslation() const;
209     static const Matrix4 Identity;
210     static constexpr int MAT_SIZE = 4;
211 };
212 
213 // Create a scale matrix with x and y scales(in xy-plane)
214 Matrix3 CreateScale(float xScale, float yScale);
215 // Create a rotation matrix about the Z axis
216 // theta is in radians
217 Matrix3 CreateRotation(float theta);
218 // Create a translation matrix (on the xy-plane)
219 Matrix3 CreateTranslation(const Vector2& trans);
220 // Create a scale matrix with x, y, and z scales
221 Matrix4 CreateScale(float xScale, float yScale, float zScale);
222 // Create a rotation matrix about X axis
223 // theta is in radians
224 Matrix4 CreateRotationX(float theta);
225 // Create a rotation matrix about Y axis
226 // theta is in radians
227 Matrix4 CreateRotationY(float theta);
228 // Create a rotation matrix about Z axis
229 // theta is in radians
230 Matrix4 CreateRotationZ(float theta);
231 // Create a 3D translation matrix
232 Matrix4 CreateTranslation(const Vector3& trans);
233 Matrix4 CreateLookAt(const Vector3& eye, const Vector3& target, const Vector3& up);
234 Matrix4 CreatePerspective(const Vector3& camera);
235 // Transform a Vector2 in xy-plane by matrix3
236 Vector2 Transform(const Vector2& vec, const Matrix3& mat);
237 // Transform a Vector3 in 3D world by matrix4
238 Vector3 Transform(const Vector3& vec, const Matrix4& mat);
239 // Transform the vector and renormalize the w component
240 Vector3 TransformWithPerspDiv(const Vector3& vec, const Matrix4& mat, float w = 1.0f);
241 // Given a screen point, unprojects it into origin position at screen,
242 // based on the current transform matrix
243 Vector2 GetOriginScreenPoint(const Vector2& p, const Matrix4& mat);
244 } // namespace TransformHelper
245 } // namespace OHOS::Rosen
246 #endif // OHOS_ROSEN_WM_MATH_H