• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-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 #include "gfx_utils/graphic_math.h"
17 #if defined(ENABLE_CMATH) && ENABLE_CMATH
18 #include <cmath>
19 #endif
20 
21 namespace OHOS {
22 #if defined(ENABLE_CMATH) && !ENABLE_CMATH
23 static float g_sinValues[] = {
24     0.000000, 0.017452, 0.034899, 0.052336, 0.069756, 0.087156, 0.104528, 0.121869, 0.139173, 0.156434, 0.173648,
25     0.190809, 0.207912, 0.224951, 0.241922, 0.258819, 0.275637, 0.292372, 0.309017, 0.325568, 0.342020, 0.358368,
26     0.374607, 0.390731, 0.406737, 0.422618, 0.438371, 0.453990, 0.469472, 0.484810, 0.500000, 0.515038, 0.529919,
27     0.544639, 0.559193, 0.573576, 0.587785, 0.601815, 0.615661, 0.629320, 0.642788, 0.656059, 0.669131, 0.681998,
28     0.694658, 0.707107, 0.719340, 0.731354, 0.743145, 0.754710, 0.766044, 0.777146, 0.788011, 0.798636, 0.809017,
29     0.819152, 0.829038, 0.838671, 0.848048, 0.857167, 0.866025, 0.874620, 0.882948, 0.891007, 0.898794, 0.906308,
30     0.913545, 0.920505, 0.927184, 0.933580, 0.939693, 0.945519, 0.951057, 0.956305, 0.961262, 0.965926, 0.970296,
31     0.974370, 0.978148, 0.981627, 0.984808, 0.987688, 0.990268, 0.992546, 0.994522, 0.996195, 0.997564, 0.998630,
32     0.999391, 0.999848, 1.000000
33 };
34 #endif
35 
Sin(float angle)36 float Sin(float angle)
37 {
38 #if defined(ENABLE_CMATH) && ENABLE_CMATH
39     float radian =  angle / RADIAN_TO_ANGLE;
40     return sin(radian);
41 #else
42     int16_t degree = static_cast<int16_t>(MATH_ROUND(angle));
43     degree = degree % CIRCLE_IN_DEGREE;
44     if (degree < 0) {
45         degree = CIRCLE_IN_DEGREE + degree;
46     }
47 
48     if (degree <= QUARTER_IN_DEGREE) {
49         return g_sinValues[degree];
50     } else if (degree <= SEMICIRCLE_IN_DEGREE) {
51         return g_sinValues[SEMICIRCLE_IN_DEGREE - degree];
52     } else if (degree <= THREE_QUARTER_IN_DEGREE) {
53         return -g_sinValues[degree - SEMICIRCLE_IN_DEGREE];
54     } else {
55         return -g_sinValues[CIRCLE_IN_DEGREE - degree];
56     }
57 #endif
58 }
59 
Fmod(float x,float y)60 float Fmod(float x, float y)
61 {
62     return static_cast<float>(x - static_cast<int>(x / y) * y);
63 }
64 
Cos(float angle)65 float Cos(float angle)
66 {
67 #if defined(ENABLE_CMATH) && ENABLE_CMATH
68     return cos(angle / RADIAN_TO_ANGLE);
69 #else
70     Sin(QUARTER_IN_DEGREE - angle);
71 #endif
72 }
73 
Acos(float value)74 float Acos(float value)
75 {
76 #if defined(ENABLE_CMATH) && ENABLE_CMATH
77     return acos(value);
78 #else
79     float result, l, r;
80     l = 0;
81     r = UI_PI;
82     result = (l + r) / 2;
83     while (MATH_ABS(Sin(QUARTER_IN_DEGREE - result * RADIAN_TO_ANGLE) - value) > UI_FLT_EPSILON) {
84         if (Sin(QUARTER_IN_DEGREE - result * RADIAN_TO_ANGLE) - value > UI_FLT_EPSILON) {
85             l = result;
86         } else {
87             r = result;
88         }
89         result = (l + r) / 2;
90     }
91     return result;
92 #endif
93 }
94 
95 /* arctan(x) = x - p3 * x^3 + p5 * x^5 - p7 * x^7 */
FastAtan2(int16_t x,int16_t y)96 uint16_t FastAtan2(int16_t x, int16_t y)
97 {
98     if (x == 0 && y == 0) {
99         return 0;
100     }
101 
102     int16_t absX = MATH_ABS(x);
103     int16_t absY = MATH_ABS(y);
104     float t;
105     float t2;
106     uint16_t angle;
107     if (absX <= absY) {
108         t = static_cast<float>(absX) / absY;
109         t2 = t * t;
110         angle = static_cast<uint16_t>(t * (1 + t2 * (ATAN2_P3 + t2 * (ATAN2_P5 + t2 * ATAN2_P7))) * RADIAN_TO_ANGLE);
111     } else {
112         t = static_cast<float>(absY) / absX;
113         t2 = t * t;
114         angle = QUARTER_IN_DEGREE -
115             static_cast<uint16_t>(t * (1 + t2 * (ATAN2_P3 + t2 * (ATAN2_P5 + t2 * ATAN2_P7))) * RADIAN_TO_ANGLE);
116     }
117 
118     if (y < 0) {
119         if (x < 0) {
120             angle = SEMICIRCLE_IN_DEGREE + angle;
121         } else {
122             angle = SEMICIRCLE_IN_DEGREE - angle;
123         }
124     } else if (x < 0) {
125         angle = CIRCLE_IN_DEGREE - angle;
126     }
127 
128     return angle;
129 }
130 
FastAtan2F(float y,float x)131 float FastAtan2F(float y, float x)
132 {
133     float absX = MATH_ABS(x);
134     float absY = MATH_ABS(y);
135     if (absY < UI_FLT_EPSILON && absX < UI_FLT_EPSILON) {
136         return 0;
137     }
138     float t;
139     float t2;
140     float angle;
141     if (absX <= absY) {
142         t = absX / absY;
143         t2 = t * t;
144         angle = UI_PI / 2 - (t * (1 + t2 * (ATAN2_P3 + t2 * (ATAN2_P5 + t2 * ATAN2_P7))));
145     } else {
146         t = (absY) / absX;
147         t2 = t * t;
148         angle = (t * (1 + t2 * (ATAN2_P3 + t2 * (ATAN2_P5 + t2 * ATAN2_P7))));
149     }
150 
151     if (y < 0) {
152         if (x < 0) {
153             angle = -UI_PI + angle;
154         } else {
155             angle = -angle;
156         }
157     } else if (x < 0) {
158         angle =  UI_PI - angle;
159     }
160 
161     return angle;
162 }
163 
Sqrt(float x)164 float Sqrt(float x)
165 {
166     const float xhalf = 0.5f * x;
167     int32_t i = *reinterpret_cast<int32_t*>(&x);
168     // 0x5f375a86 : Initial value of Newton Iterator. 2 : initial parameter for iterator.
169     i = 0x5f375a86 - (i / 2);
170     float y = *reinterpret_cast<float*>(&i);
171     y = y * (1.5f - (xhalf * y * y));
172     y = y * (1.5f - (xhalf * y * y));
173     y = y * (1.5f - (xhalf * y * y));
174     return x * y;
175 }
176 
IsIdentity(Matrix3<float> & matrix)177 bool IsIdentity(Matrix3<float>& matrix)
178 {
179     // check m00 m11 m22
180     if (!FloatEqual(matrix[0][0], 1) || !FloatEqual(matrix[1][1], 1) || !FloatEqual(matrix[2][2], 1)) {
181         return false;
182     }
183     // check others
184     if (!FloatEqual(matrix[0][1], 0) || !FloatEqual(matrix[0][2], 0) ||
185         !FloatEqual(matrix[2][0], 0) || !FloatEqual(matrix[2][1], 0) ||
186         !FloatEqual(matrix[1][0], 0) || !FloatEqual(matrix[1][2], 0)) {
187         return false;
188     }
189     return true;
190 }
191 
IsIdentity(Matrix4<float> & matrix)192 bool IsIdentity(Matrix4<float>& matrix)
193 {
194     for (int16_t row = 0; row < ORDER_MATRIX_4; row++) {
195         for (int16_t col = 0; col < ORDER_MATRIX_4; col++) {
196             bool flag = (row == col) ? FloatEqual(matrix[row][col], 1) : FloatEqual(matrix[row][col], 0);
197             if (!flag) {
198                 return false;
199             }
200         }
201     }
202     return true;
203 }
204 } // namespace OHOS
205