]> git.tdb.fi Git - libs/math.git/blob - source/geometry/angle.h
edd752122f3436055028f6dab93332f3836a0f96
[libs/math.git] / source / geometry / angle.h
1 #ifndef MSP_GEOMETRY_ANGLE_H_
2 #define MSP_GEOMETRY_ANGLE_H_
3
4 #include <cmath>
5
6 namespace Msp {
7 namespace Geometry {
8
9 /**
10 A planar angle.  Creating an Angle from a raw value or extracting it requires
11 specifying whether degrees or radians are used.  This eliminates a common
12 source of errors.
13 */
14 template<typename T>
15 class Angle
16 {
17 private:
18         T value;
19
20         explicit Angle(T);
21 public:
22         template<typename U>
23         Angle(const Angle<U> &);
24
25         static Angle from_degrees(T);
26         static Angle from_radians(T);
27
28         static Angle right();
29         static Angle quarter_circle();
30         static Angle straight();
31         static Angle half_circle();
32         static Angle full_circle();
33
34         T degrees() const;
35         T radians() const;
36
37         Angle &operator+=(const Angle &);
38         Angle &operator-=(const Angle &);
39         Angle &operator*=(T);
40         Angle &operator/=(T);
41 };
42
43 template<typename T>
44 inline Angle<T>::Angle(T v):
45         value(v)
46 { }
47
48 template<typename T>
49 template<typename U>
50 inline Angle<T>::Angle(const Angle<U> &other):
51         value(other.value)
52 { }
53
54 template<typename T>
55 inline Angle<T> Angle<T>::from_degrees(T d)
56 {
57         return Angle<T>(d*M_PI/180);
58 }
59
60 template<typename T>
61 inline Angle<T> Angle<T>::from_radians(T r)
62 {
63         return Angle<T>(r);
64 }
65
66 template<typename T>
67 inline Angle<T> Angle<T>::right()
68 {
69         return from_radians(M_PI/2);
70 }
71
72 template<typename T>
73 inline Angle<T> Angle<T>::quarter_circle()
74 {
75         return right();
76 }
77
78 template<typename T>
79 inline Angle<T> Angle<T>::straight()
80 {
81         return from_radians(M_PI);
82 }
83
84 template<typename T>
85 inline Angle<T> Angle<T>::half_circle()
86 {
87         return straight();
88 }
89
90 template<typename T>
91 inline Angle<T> Angle<T>::full_circle()
92 {
93         return from_radians(M_PI*2);
94 }
95
96 template<typename T>
97 inline T Angle<T>::degrees() const
98 {
99         return value*180/M_PI;
100 }
101
102 template<typename T>
103 inline T Angle<T>::radians() const
104 {
105         return value;
106 }
107
108 template<typename T>
109 inline Angle<T> &Angle<T>::operator+=(const Angle &a)
110 {
111         value += a.value;
112         return *this;
113 }
114
115 template<typename T>
116 inline Angle<T> operator+(const Angle<T> &a1, const Angle<T> &a2)
117 {
118         Angle<T> r(a1);
119         return r += a2;
120 }
121
122 template<typename T>
123 inline Angle<T> &Angle<T>::operator-=(const Angle &a)
124 {
125         value -= a.value;
126         return *this;
127 }
128
129 template<typename T>
130 inline Angle<T> operator-(const Angle<T> &a1, const Angle<T> &a2)
131 {
132         Angle<T> r(a1);
133         return r -= a2;
134 }
135
136 template<typename T>
137 inline Angle<T> &Angle<T>::operator*=(T s)
138 {
139         value *= s;
140         return *this;
141 }
142
143 template<typename T>
144 inline Angle<T> operator*(const Angle<T> &a, T s)
145 {
146         Angle<T> r(a);
147         return r *= s;
148 }
149
150 template<typename T>
151 inline Angle<T> operator*(T s, const Angle<T> &a)
152 {
153         return a*s;
154 }
155
156 template<typename T>
157 inline Angle<T> &Angle<T>::operator/=(T s)
158 {
159         value /= s;
160         return *this;
161 }
162
163 template<typename T>
164 inline Angle<T> operator/(const Angle<T> &a, T s)
165 {
166         Angle<T> r(a);
167         return r /= s;
168 }
169
170 template<typename T>
171 inline Angle<T> operator/(T s, const Angle<T> &a)
172 {
173         return a/s;
174 }
175
176 template<typename T>
177 inline T sin(const Angle<T> &angle)
178 {
179         return std::sin(angle.radians());
180 }
181
182 template<typename T>
183 inline Angle<T> asin(T s)
184 {
185         return Angle<T>::from_radians(std::asin(s));
186 }
187
188 template<typename T>
189 inline T cos(const Angle<T> &angle)
190 {
191         return std::cos(angle.radians());
192 }
193
194 template<typename T>
195 inline Angle<T> acos(T s)
196 {
197         return Angle<T>::from_radians(std::acos(s));
198 }
199
200 template<typename T>
201 inline T tan(const Angle<T> &angle)
202 {
203         return std::tan(angle.radians());
204 }
205
206 template<typename T>
207 inline Angle<T> atan(T s)
208 {
209         return Angle<T>::from_radians(std::atan(s));
210 }
211
212 template<typename T>
213 inline Angle<T> atan2(T y, T x)
214 {
215         return Angle<T>::from_radians(std::atan2(y, x));
216 }
217
218 } // namespace Geometry
219 } // namespace Msp
220
221 #endif