1 | // Copyright 2003 Google, Inc. |
2 | // All Rights Reserved. |
3 | // |
4 | // |
5 | // A simple class to handle vectors in 2D |
6 | // The aim of this class is to be able to manipulate vectors in 2D |
7 | // as naturally as possible and make calculations readable. |
8 | // For that reason, the operators +, -, * are overloaded. |
9 | // (Reading a = a + b*2 - c is much easier to read than |
10 | // a = Sub(Add(a, Mul(b,2)),c) ) |
11 | // The code generated using this vector class is easily optimized by |
12 | // the compiler and does not generate overhead compared to manually |
13 | // writing the operations component by component |
14 | // (e.g a.x = b.x + c.x; a.y = b.y + c.y...) |
15 | // |
16 | // Operator overload is not usually allowed, but in this case an |
17 | // exemption has been granted by the C++ style committee. |
18 | // |
19 | // Please be careful about overflows when using those vectors with integer types |
20 | // The calculations are carried with the same type as the vector's components |
21 | // type. eg : if you are using uint8 as the base type, all values will be modulo |
22 | // 256. |
23 | // This feature is necessary to use the class in a more general framework with |
24 | // VType != plain old data type. |
25 | |
26 | #ifndef UTIL_MATH_VECTOR2_INL_H__ |
27 | #define UTIL_MATH_VECTOR2_INL_H__ |
28 | |
29 | #include "util/math/vector2.h" |
30 | |
31 | #include <math.h> |
32 | #include "base/basictypes.h" |
33 | #include "base/logging.h" |
34 | #include "base/template_util.h" |
35 | #include "base/type_traits.h" |
36 | #include "util/math/mathutil.h" |
37 | #include "util/math/vector3.h" |
38 | #include "util/math/vector4.h" |
39 | |
40 | template <typename VType> |
41 | Vector2<VType>::Vector2() { |
42 | Clear(); |
43 | } |
44 | template <typename VType> |
45 | Vector2<VType>::Vector2(const VType x, const VType y) { |
46 | c_[0] = x; |
47 | c_[1] = y; |
48 | } |
49 | template <typename VType> |
50 | Vector2<VType>::Vector2(const Self &vb) { |
51 | c_[0] = vb.c_[0]; |
52 | c_[1] = vb.c_[1]; |
53 | } |
54 | template <typename VType> |
55 | Vector2<VType>::Vector2(const Vector3<VType> &vb) { |
56 | c_[0] = vb.x(); |
57 | c_[1] = vb.y(); |
58 | } |
59 | template <typename VType> |
60 | Vector2<VType>::Vector2(const Vector4<VType> &vb) { |
61 | c_[0] = vb.x(); |
62 | c_[1] = vb.y(); |
63 | } |
64 | |
65 | template <typename VType> template <typename VType2> |
66 | Vector2<VType> Vector2<VType>::Cast(const Vector2<VType2> &vb) { |
67 | return Self(static_cast<VType>(vb[0]), |
68 | static_cast<VType>(vb[1])); |
69 | } |
70 | |
71 | template <typename VType> |
72 | void Vector2<VType>::Set(const VType x, const VType y) { |
73 | c_[0] = x; |
74 | c_[1] = y; |
75 | } |
76 | |
77 | template <typename VType> |
78 | const Vector2<VType>& Vector2<VType>::operator=(const Self &vb) { |
79 | c_[0] = vb.c_[0]; |
80 | c_[1] = vb.c_[1]; |
81 | return (*this); |
82 | } |
83 | |
84 | template <typename VType> |
85 | Vector2<VType>& Vector2<VType>::operator+=(const Self &vb) { |
86 | c_[0] += vb.c_[0]; |
87 | c_[1] += vb.c_[1]; |
88 | return (*this); |
89 | } |
90 | |
91 | template <typename VType> |
92 | Vector2<VType>& Vector2<VType>::operator-=(const Self &vb) { |
93 | c_[0] -= vb.c_[0]; |
94 | c_[1] -= vb.c_[1]; |
95 | return (*this); |
96 | } |
97 | |
98 | template <typename VType> |
99 | Vector2<VType>& Vector2<VType>::operator*=(const VType k) { |
100 | c_[0] *= k; |
101 | c_[1] *= k; |
102 | return (*this); |
103 | } |
104 | |
105 | template <typename VType> |
106 | Vector2<VType>& Vector2<VType>::operator/=(const VType k) { |
107 | c_[0] /= k; |
108 | c_[1] /= k; |
109 | return (*this); |
110 | } |
111 | |
112 | template <typename VType> |
113 | Vector2<VType> Vector2<VType>::MulComponents(const Self &vb) const { |
114 | return Self(c_[0] * vb.c_[0], c_[1] * vb.c_[1]); |
115 | } |
116 | |
117 | template <typename VType> |
118 | Vector2<VType> Vector2<VType>::DivComponents(const Self &vb) const { |
119 | return Self(c_[0] / vb.c_[0], c_[1] / vb.c_[1]); |
120 | } |
121 | |
122 | template <typename VType> |
123 | Vector2<VType> Vector2<VType>::operator+(const Self &vb) const { |
124 | return Self(*this) += vb; |
125 | } |
126 | |
127 | template <typename VType> |
128 | Vector2<VType> Vector2<VType>::operator-(const Self &vb) const { |
129 | return Self(*this) -= vb; |
130 | } |
131 | |
132 | template <typename VType> |
133 | Vector2<VType> Vector2<VType>::operator-() const { |
134 | return Self(-c_[0], -c_[1]); |
135 | } |
136 | |
137 | template <typename VType> |
138 | VType Vector2<VType>::DotProd(const Self &vb) const { |
139 | return c_[0] * vb.c_[0] + c_[1] * vb.c_[1]; |
140 | } |
141 | |
142 | template <typename VType> |
143 | Vector2<VType> Vector2<VType>::operator*(const VType k) const { |
144 | return Self(*this) *= k; |
145 | } |
146 | |
147 | template <typename VType> |
148 | Vector2<VType> Vector2<VType>::operator/(const VType k) const { |
149 | return Self(*this) /= k; |
150 | } |
151 | |
152 | template <typename VType> |
153 | VType Vector2<VType>::CrossProd(const Self &vb) const { |
154 | return c_[0] * vb.c_[1] - c_[1] * vb.c_[0]; |
155 | } |
156 | |
157 | template <typename VType> |
158 | VType& Vector2<VType>::operator[](const int b) { |
159 | DCHECK(b >= 0); |
160 | DCHECK(b <= 1); |
161 | return c_[b]; |
162 | } |
163 | |
164 | template <typename VType> |
165 | VType Vector2<VType>::operator[](const int b) const { |
166 | DCHECK(b >= 0); |
167 | DCHECK(b <= 1); |
168 | return c_[b]; |
169 | } |
170 | |
171 | template <typename VType> |
172 | void Vector2<VType>::x(const VType &v) { |
173 | c_[0] = v; |
174 | } |
175 | |
176 | template <typename VType> |
177 | VType Vector2<VType>::x() const { |
178 | return c_[0]; |
179 | } |
180 | |
181 | template <typename VType> |
182 | void Vector2<VType>::y(const VType &v) { |
183 | c_[1] = v; |
184 | } |
185 | |
186 | template <typename VType> |
187 | VType Vector2<VType>::y() const { |
188 | return c_[1]; |
189 | } |
190 | |
191 | |
192 | |
193 | template <typename VType> |
194 | VType* Vector2<VType>::Data() { |
195 | return reinterpret_cast<VType*>(c_); |
196 | } |
197 | |
198 | template <typename VType> |
199 | const VType* Vector2<VType>::Data() const { |
200 | return reinterpret_cast<const VType*>(c_); |
201 | } |
202 | |
203 | |
204 | template <typename VType> |
205 | VType Vector2<VType>::Norm2(void) const { |
206 | return c_[0]*c_[0] + c_[1]*c_[1]; |
207 | } |
208 | |
209 | |
210 | template <typename VType> |
211 | typename Vector2<VType>::FloatType Vector2<VType>::Norm(void) const { |
212 | return sqrt(Norm2()); |
213 | } |
214 | |
215 | template <typename VType> |
216 | typename Vector2<VType>::FloatType Vector2<VType>::Angle(const Self &v) const { |
217 | return atan2(this->CrossProd(v), this->DotProd(v)); |
218 | } |
219 | |
220 | template <typename VType> |
221 | Vector2<VType> Vector2<VType>::Normalize() const { |
222 | COMPILE_ASSERT(!base::is_integral<VType>::value, must_be_floating_point); |
223 | VType n = Norm(); |
224 | if (n != 0) { |
225 | n = 1.0 / n; |
226 | } |
227 | return Self(*this) *= n; |
228 | } |
229 | |
230 | template <typename VType> |
231 | bool Vector2<VType>::operator==(const Self &vb) const { |
232 | return (c_[0] == vb.c_[0]) && (c_[1] == vb.c_[1]); |
233 | } |
234 | |
235 | template <typename VType> |
236 | bool Vector2<VType>::operator!=(const Self &vb) const { |
237 | return (c_[0] != vb.c_[0]) || (c_[1] != vb.c_[1]); |
238 | } |
239 | |
240 | template <typename VType> |
241 | bool Vector2<VType>::aequal(const Self &vb, FloatType margin) const { |
242 | return (fabs(c_[0]-vb.c_[0]) < margin) && (fabs(c_[1]-vb.c_[1]) < margin); |
243 | } |
244 | |
245 | template <typename VType> |
246 | bool Vector2<VType>::operator<(const Self &vb) const { |
247 | if ( c_[0] < vb.c_[0] ) return true; |
248 | if ( vb.c_[0] < c_[0] ) return false; |
249 | if ( c_[1] < vb.c_[1] ) return true; |
250 | return false; |
251 | } |
252 | |
253 | template <typename VType> |
254 | bool Vector2<VType>::operator>(const Self &vb) const { |
255 | return vb.operator<(*this); |
256 | } |
257 | |
258 | template <typename VType> |
259 | bool Vector2<VType>::operator<=(const Self &vb) const { |
260 | return !operator>(vb); |
261 | } |
262 | |
263 | template <typename VType> |
264 | bool Vector2<VType>::operator>=(const Self &vb) const { |
265 | return !operator<(vb); |
266 | } |
267 | |
268 | template <typename VType> |
269 | Vector2<VType> Vector2<VType>::Ortho() const { |
270 | return Self(-c_[1], c_[0]); |
271 | } |
272 | |
273 | template <typename VType> |
274 | Vector2<VType> Vector2<VType>::Sqrt() const { |
275 | return Self(sqrt(c_[0]), sqrt(c_[1])); |
276 | } |
277 | |
278 | template <typename VType> |
279 | Vector2<VType> Vector2<VType>::Fabs() const { |
280 | return Self(fabs(c_[0]), fabs(c_[1])); |
281 | } |
282 | |
283 | template <typename VType> |
284 | Vector2<VType> Vector2<VType>::Abs() const { |
285 | COMPILE_ASSERT(base::is_integral<VType>::value, use_Fabs_for_float_types); |
286 | COMPILE_ASSERT(static_cast<VType>(-1) == -1, type_must_be_signed); |
287 | COMPILE_ASSERT(sizeof(VType) <= sizeof(int), Abs_truncates_to_int); |
288 | return Self(abs(c_[0]), abs(c_[1])); |
289 | } |
290 | |
291 | template <typename VType> |
292 | Vector2<VType> Vector2<VType>::Floor() const { |
293 | return Self(floor(c_[0]), floor(c_[1])); |
294 | } |
295 | |
296 | |
297 | template <typename VType> |
298 | Vector2<VType> Vector2<VType>::Ceil() const { |
299 | return Self(ceil(c_[0]), ceil(c_[1])); |
300 | } |
301 | |
302 | |
303 | template <typename VType> |
304 | Vector2<VType> Vector2<VType>::FRound() const { |
305 | return Self(rint(c_[0]), rint(c_[1])); |
306 | } |
307 | |
308 | template <typename VType> |
309 | Vector2<int> Vector2<VType>::IRound() const { |
310 | return Vector2<int>(lrint(c_[0]), lrint(c_[1])); |
311 | } |
312 | |
313 | template <typename VType> |
314 | void Vector2<VType>::Clear() { |
315 | c_[1] = c_[0] = VType(); |
316 | } |
317 | |
318 | template <typename VType> |
319 | bool Vector2<VType>::IsNaN() const { |
320 | return isnan(c_[0]) || isnan(c_[1]); |
321 | } |
322 | |
323 | template <typename VType> |
324 | Vector2<VType> Vector2<VType>::NaN() { |
325 | return Self(MathUtil::NaN(), MathUtil::NaN()); |
326 | } |
327 | |
328 | template <typename ScalarType, typename VType2> |
329 | Vector2<VType2> operator*(const ScalarType k, const Vector2<VType2> v) { |
330 | return Vector2<VType2>( k * v[0], k * v[1]); |
331 | } |
332 | |
333 | template <typename ScalarType, typename VType2> |
334 | Vector2<VType2> operator/(const ScalarType k, const Vector2<VType2> v) { |
335 | return Vector2<VType2>(k / v[0], k / v[1]); |
336 | } |
337 | |
338 | template <typename VType> |
339 | Vector2<VType> Max(const Vector2<VType> &v1, const Vector2<VType> &v2) { |
340 | return Vector2<VType>(max(v1[0], v2[0]), max(v1[1], v2[1])); |
341 | } |
342 | |
343 | template <typename VType> |
344 | Vector2<VType> Min(const Vector2<VType> &v1, const Vector2<VType> &v2) { |
345 | return Vector2<VType>(min(v1[0], v2[0]), min(v1[1], v2[1])); |
346 | } |
347 | |
348 | template <typename VType> |
349 | std::ostream &operator <<(std::ostream &out, const Vector2<VType> &va) { |
350 | out << "[" |
351 | << va[0] << ", " |
352 | << va[1] << "]" ; |
353 | return out; |
354 | } |
355 | |
356 | // TODO(user): Vector2<T> does not actually satisfy the definition of a POD |
357 | // type even when T is a POD. Pretending that Vector2<T> is a POD probably |
358 | // won't cause any immediate problems, but eventually this should be fixed. |
359 | PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(Vector2); |
360 | |
361 | #endif // UTIL_MATH_VECTOR2_INL_H__ |
362 | |