Overte C++ Documentation
AngleUtil.h
1 //
2 // AngleUtil.h
3 // libraries/shared/src
4 //
5 // Created by Tobias Schwinger on 3/23/13.
6 // Copyright 2013 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 #ifndef hifi_AngleUtil_h
13 #define hifi_AngleUtil_h
14 
15 #include <math.h>
16 
17 struct Degrees {
18 
19  static float pi() { return 180.0f; }
20  static float twicePi() { return 360.0f; }
21  static float halfPi() { return 90.0f; }
22 };
23 
24 struct Radians {
25 
26  static float pi() { return 3.141592653589793f; }
27  static float twicePi() { return 6.283185307179586f; }
28  static float halfPi() { return 1.5707963267948966f; }
29 };
30 
31 struct Rotations {
32 
33  static float pi() { return 0.5f; }
34  static float twicePi() { return 1.0f; }
35  static float halfPi() { return 0.25f; }
36 };
37 
38 //
39 // Converts an angle from one unit to another.
40 //
41 template< class UnitFrom, class UnitTo >
42 float angleConvert(float a) {
43 
44  return a * (UnitTo::halfPi() / UnitFrom::halfPi());
45 }
46 
47 
48 //
49 // Clamps an angle to the range of [-180; 180) degrees.
50 //
51 template< class Unit >
52 float angleSignedNormal(float a) {
53 
54  // result is remainder(a, Unit::twicePi());
55  float result = fmod(a, Unit::twicePi());
56  if (result >= Unit::pi()) {
57 
58  result -= Unit::twicePi();
59 
60  } else if (result < -Unit::pi()) {
61 
62  result += Unit::twicePi();
63  }
64  return result;
65 }
66 
67 //
68 // Clamps an angle to the range of [0; 360) degrees.
69 //
70 template< class Unit >
71 float angleUnsignedNormal(float a) {
72 
73  return angleSignedNormal<Unit>(a - Unit::pi()) + Unit::pi();
74 }
75 
76 
77 //
78 // Clamps a polar direction so that azimuth is in the range of [0; 360)
79 // degrees and altitude is in the range of [-90; 90] degrees.
80 //
81 // The so normalized angle still contains ambiguity due to gimbal lock:
82 // Both poles can be reached from any azimuthal direction.
83 //
84 template< class Unit >
85 void angleHorizontalPolar(float& azimuth, float& altitude) {
86 
87  altitude = angleSignedNormal<Unit>(altitude);
88  if (altitude > Unit::halfPi()) {
89 
90  altitude = Unit::pi() - altitude;
91  azimuth += Unit::pi();
92 
93  } else if (altitude < -Unit::halfPi()) {
94 
95  altitude = -Unit::pi() - altitude;
96  azimuth += Unit::pi();
97  }
98  azimuth = angleUnsignedNormal<Unit>(azimuth);
99 }
100 
101 #endif // hifi_AngleUtil_h