1 #ifndef MSP_GEOMETRY_ANGLE_H_
2 #define MSP_GEOMETRY_ANGLE_H_
10 A planar angle. Creating an Angle from a raw value or extracting it requires
11 specifying the units used. This eliminates a common source of errors.
19 explicit Angle(T v): value(v) { }
23 Angle(const Angle<U> &other): value(other.radians()) { }
25 static Angle from_degrees(T);
26 static Angle from_radians(T);
27 static Angle from_turns(T);
29 static Angle zero() { return from_radians(0); }
30 static Angle right() { return from_turns(0.25); }
31 static Angle quarter_turn() { return right(); }
32 static Angle straight() { return from_turns(0.5); }
33 static Angle half_turn() { return straight(); }
34 static Angle full_turn() { return from_turns(1); }
36 T degrees() const { return value*57.2957795130823208768; }
37 T radians() const { return value; }
38 T turns() const { return value/6.28318530717958647692; }
40 Angle &operator+=(const Angle &);
41 Angle &operator-=(const Angle &);
45 bool operator==(const Angle &other) const { return value==other.value; }
46 bool operator!=(const Angle &other) const { return value!=other.value; }
47 bool operator<(const Angle &other) const { return value<other.value; }
48 bool operator<=(const Angle &other) const { return value<=other.value; }
49 bool operator>(const Angle &other) const { return value>other.value; }
50 bool operator>=(const Angle &other) const { return value>=other.value; }
52 Angle &wrap_with_base(const Angle &);
53 Angle &wrap_positive();
54 Angle &wrap_balanced();
58 inline Angle<T> Angle<T>::from_degrees(T d)
60 return Angle<T>(d/57.2957795130823208768);
64 inline Angle<T> Angle<T>::from_radians(T r)
70 inline Angle<T> Angle<T>::from_turns(T t)
72 return Angle<T>(t*6.28318530717958647692);
76 inline Angle<T> &Angle<T>::operator+=(const Angle &a)
83 inline Angle<T> operator+(const Angle<T> &a1, const Angle<T> &a2)
90 inline Angle<T> &Angle<T>::operator-=(const Angle &a)
97 inline Angle<T> operator-(const Angle<T> &a1, const Angle<T> &a2)
104 inline Angle<T> operator-(const Angle<T> &a)
106 return Angle<T>::zero()-a;
110 inline Angle<T> &Angle<T>::operator*=(T s)
117 inline Angle<T> operator*(const Angle<T> &a, T s)
124 inline Angle<T> operator*(T s, const Angle<T> &a)
130 inline Angle<T> &Angle<T>::operator/=(T s)
137 inline Angle<T> operator/(const Angle<T> &a, T s)
144 inline Angle<T> operator/(T s, const Angle<T> &a)
150 inline T operator/(const Angle<T> &a1, const Angle<T> &a2)
152 return a1.radians()/a2.radians();
156 inline Angle<T> &Angle<T>::wrap_with_base(const Angle<T> &b)
158 const T two_pi = 6.28318530717958647692;
161 while(value>=b.value+two_pi)
167 inline Angle<T> &Angle<T>::wrap_positive()
169 return wrap_with_base(zero());
173 inline Angle<T> &Angle<T>::wrap_balanced()
175 return wrap_with_base(-half_turn());
179 inline Angle<T> wrap_with_base(const Angle<T> &a, const Angle<T> &b)
182 return r.wrap_with_base(b);
186 inline Angle<T> wrap_positive(const Angle<T> &a)
189 return r.wrap_positive();
193 inline Angle<T> wrap_balanced(const Angle<T> &a)
196 return r.wrap_balanced();
200 inline Angle<T> abs(const Angle<T> &angle)
203 return Angle<T>::from_radians(abs(angle.radians()));
207 inline T sin(const Angle<T> &angle)
210 return sin(angle.radians());
214 inline Angle<T> asin(T s)
217 return Angle<T>::from_radians(asin(s));
221 inline T cos(const Angle<T> &angle)
224 return cos(angle.radians());
228 inline Angle<T> acos(T s)
231 return Angle<T>::from_radians(acos(s));
235 inline T tan(const Angle<T> &angle)
238 return tan(angle.radians());
242 inline Angle<T> atan(T s)
245 return Angle<T>::from_radians(atan(s));
249 inline Angle<T> atan2(T y, T x)
252 return Angle<T>::from_radians(atan2(y, x));
255 } // namespace Geometry