-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathatan2.h
77 lines (59 loc) · 1.53 KB
/
atan2.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#ifndef ATAN2_H
#define ATAN2_H
#include <math.h>
static inline float atan2_libm(float complex y)
{
return cargf(y) * (float)M_1_PI;
}
/** https://gist.github.com/volkansalma/2972237 */
static inline float atan2_approximation(float complex s)
{
static const float ONEQTR_PI = M_PI / 4.0;
static const float THRQTR_PI = 3.0 * M_PI / 4.0;
float y = cimagf(s), x = crealf(s);
float r, angle;
float abs_y = fabs(y) + 1e-10f; // kludge to prevent 0/0 condition
if (x < 0.0f)
{
r = (x + abs_y) / (abs_y - x);
angle = THRQTR_PI;
}
else
{
r = (x - abs_y) / (x + abs_y);
angle = ONEQTR_PI;
}
angle += (0.1963f*(float)M_1_PI * r * r - 0.9817f*(float)M_1_PI) * r;
if (y < 0.0f)
angle = -angle; // negate if in quad III or IV
return angle;
}
/** https://gist.github.com/volkansalma/2972237 */
static inline float atan2_approximation2(float complex s)
{
float y = cimagf(s), x = crealf(s);
if (x == 0.0f)
{
if (y > 0.0f) return 0.5f;
if (y == 0.0f) return 0.0f;
return -0.5f;
}
float atan;
const float z = y / x;
if (fabs(z) < 1.0f)
{
atan = z / (1.0f*(float)M_PI + 0.28086f*(float)M_PI*z*z);
if (x < 0.0f)
{
if (y < 0.0f) return atan - 1.0f;
return atan + 1.0f;
}
}
else
{
atan = 0.5f - z / (z*z + 0.28086f) * (float)M_1_PI;
if ( y < 0.0f ) return atan - 1.0f;
}
return atan;
}
#endif /* ATAN2_H */