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.value) { }
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_radians(M_PI/2); }
31 static Angle quarter_turn() { return right(); }
32 static Angle straight() { return from_radians(M_PI); }
33 static Angle half_turn() { return straight(); }
34 static Angle full_turn() { return from_radians(2*M_PI); }
36 T degrees() const { return value*180/M_PI; }
37 T radians() const { return value; }
38 T turns() const { return value/(2*M_PI); }
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*M_PI/180);
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*2*M_PI);
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)
160 while(value>=b.value+2*M_PI)
166 inline Angle<T> &Angle<T>::wrap_positive()
168 return wrap_with_base(zero());
172 inline Angle<T> &Angle<T>::wrap_balanced()
174 return wrap_with_base(-half_turn());
178 inline Angle<T> wrap_with_base(const Angle<T> &a, const Angle<T> &b)
181 return r.wrap_with_base(b);
185 inline Angle<T> wrap_positive(const Angle<T> &a)
188 return r.wrap_positive();
192 inline Angle<T> wrap_balanced(const Angle<T> &a)
195 return r.wrap_balanced();
199 inline Angle<T> abs(const Angle<T> &angle)
201 return Angle<T>::from_radians(std::abs(angle.radians()));
205 inline T sin(const Angle<T> &angle)
207 return std::sin(angle.radians());
211 inline Angle<T> asin(T s)
213 return Angle<T>::from_radians(std::asin(s));
217 inline T cos(const Angle<T> &angle)
219 return std::cos(angle.radians());
223 inline Angle<T> acos(T s)
225 return Angle<T>::from_radians(std::acos(s));
229 inline T tan(const Angle<T> &angle)
231 return std::tan(angle.radians());
235 inline Angle<T> atan(T s)
237 return Angle<T>::from_radians(std::atan(s));
241 inline Angle<T> atan2(T y, T x)
243 return Angle<T>::from_radians(std::atan2(y, x));
246 } // namespace Geometry