vector2-inl.h
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/integral_types.h"
33 
34 #include "base/type_traits.h"
35 #include "util/math/mathutil.h"
36 #include "util/math/vector3.h"
37 #include "util/math/vector4.h"
38 
39 template <typename VType>
41  Clear();
42 }
43 template <typename VType>
44 Vector2<VType>::Vector2(const VType x, const VType y) {
45  c_[0] = x;
46  c_[1] = y;
47 }
48 template <typename VType>
49 Vector2<VType>::Vector2(const Self &vb) {
50  c_[0] = vb.c_[0];
51  c_[1] = vb.c_[1];
52 }
53 template <typename VType>
55  c_[0] = vb.x();
56  c_[1] = vb.y();
57 }
58 template <typename VType>
60  c_[0] = vb.x();
61  c_[1] = vb.y();
62 }
63 
64 template <typename VType> template <typename VType2>
66  return Self(static_cast<VType>(vb[0]),
67  static_cast<VType>(vb[1]));
68 }
69 
70 template <typename VType>
71 void Vector2<VType>::Set(const VType x, const VType y) {
72  c_[0] = x;
73  c_[1] = y;
74 }
75 
76 template <typename VType>
77 const Vector2<VType>& Vector2<VType>::operator=(const Self &vb) {
78  c_[0] = vb.c_[0];
79  c_[1] = vb.c_[1];
80  return (*this);
81 }
82 
83 template <typename VType>
85  c_[0] += vb.c_[0];
86  c_[1] += vb.c_[1];
87  return (*this);
88 }
89 
90 template <typename VType>
92  c_[0] -= vb.c_[0];
93  c_[1] -= vb.c_[1];
94  return (*this);
95 }
96 
97 template <typename VType>
99  c_[0] *= k;
100  c_[1] *= k;
101  return (*this);
102 }
103 
104 template <typename VType>
106  c_[0] /= k;
107  c_[1] /= k;
108  return (*this);
109 }
110 
111 template <typename VType>
112 Vector2<VType> Vector2<VType>::MulComponents(const Self &vb) const {
113  return Self(c_[0] * vb.c_[0], c_[1] * vb.c_[1]);
114 }
115 
116 template <typename VType>
117 Vector2<VType> Vector2<VType>::DivComponents(const Self &vb) const {
118  return Self(c_[0] / vb.c_[0], c_[1] / vb.c_[1]);
119 }
120 
121 template <typename VType>
122 Vector2<VType> Vector2<VType>::operator+(const Self &vb) const {
123  return Self(*this) += vb;
124 }
125 
126 template <typename VType>
127 Vector2<VType> Vector2<VType>::operator-(const Self &vb) const {
128  return Self(*this) -= vb;
129 }
130 
131 template <typename VType>
133  return Self(-c_[0], -c_[1]);
134 }
135 
136 template <typename VType>
137 VType Vector2<VType>::DotProd(const Self &vb) const {
138  return c_[0] * vb.c_[0] + c_[1] * vb.c_[1];
139 }
140 
141 template <typename VType>
142 Vector2<VType> Vector2<VType>::operator*(const VType k) const {
143  return Self(*this) *= k;
144 }
145 
146 template <typename VType>
147 Vector2<VType> Vector2<VType>::operator/(const VType k) const {
148  return Self(*this) /= k;
149 }
150 
151 template <typename VType>
152 VType Vector2<VType>::CrossProd(const Self &vb) const {
153  return c_[0] * vb.c_[1] - c_[1] * vb.c_[0];
154 }
155 
156 template <typename VType>
157 VType& Vector2<VType>::operator[](const int b) {
158  DCHECK(b >= 0);
159  DCHECK(b <= 1);
160  return c_[b];
161 }
162 
163 template <typename VType>
164 VType Vector2<VType>::operator[](const int b) const {
165  DCHECK(b >= 0);
166  DCHECK(b <= 1);
167  return c_[b];
168 }
169 
170 template <typename VType>
171 void Vector2<VType>::x(const VType &v) {
172  c_[0] = v;
173 }
174 
175 template <typename VType>
176 VType Vector2<VType>::x() const {
177  return c_[0];
178 }
179 
180 template <typename VType>
181 void Vector2<VType>::y(const VType &v) {
182  c_[1] = v;
183 }
184 
185 template <typename VType>
186 VType Vector2<VType>::y() const {
187  return c_[1];
188 }
189 
190 
191 
192 template <typename VType>
193 VType* Vector2<VType>::Data() {
194  return reinterpret_cast<VType*>(c_);
195 }
196 
197 template <typename VType>
198 const VType* Vector2<VType>::Data() const {
199  return reinterpret_cast<const VType*>(c_);
200 }
201 
202 
203 template <typename VType>
204 VType Vector2<VType>::Norm2(void) const {
205  return c_[0]*c_[0] + c_[1]*c_[1];
206 }
207 
208 
209 template <typename VType>
210 typename Vector2<VType>::FloatType Vector2<VType>::Norm(void) const {
211  return sqrt(Norm2());
212 }
213 
214 template <typename VType>
215 typename Vector2<VType>::FloatType Vector2<VType>::Angle(const Self &v) const {
216  return atan2(this->CrossProd(v), this->DotProd(v));
217 }
218 
219 template <typename VType>
221  COMPILE_ASSERT(!std::is_integral<VType>::value, must_be_floating_point);
222  VType n = Norm();
223  if (n != 0) {
224  n = 1.0 / n;
225  }
226  return Self(*this) *= n;
227 }
228 
229 template <typename VType>
230 bool Vector2<VType>::operator==(const Self &vb) const {
231  return (c_[0] == vb.c_[0]) && (c_[1] == vb.c_[1]);
232 }
233 
234 template <typename VType>
235 bool Vector2<VType>::operator!=(const Self &vb) const {
236  return (c_[0] != vb.c_[0]) || (c_[1] != vb.c_[1]);
237 }
238 
239 template <typename VType>
240 bool Vector2<VType>::aequal(const Self &vb, FloatType margin) const {
241  return (fabs(c_[0]-vb.c_[0]) < margin) && (fabs(c_[1]-vb.c_[1]) < margin);
242 }
243 
244 template <typename VType>
245 bool Vector2<VType>::operator<(const Self &vb) const {
246  if ( c_[0] < vb.c_[0] ) return true;
247  if ( vb.c_[0] < c_[0] ) return false;
248  if ( c_[1] < vb.c_[1] ) return true;
249  return false;
250 }
251 
252 template <typename VType>
253 bool Vector2<VType>::operator>(const Self &vb) const {
254  return vb.operator<(*this);
255 }
256 
257 template <typename VType>
258 bool Vector2<VType>::operator<=(const Self &vb) const {
259  return !operator>(vb);
260 }
261 
262 template <typename VType>
263 bool Vector2<VType>::operator>=(const Self &vb) const {
264  return !operator<(vb);
265 }
266 
267 template <typename VType>
269  return Self(-c_[1], c_[0]);
270 }
271 
272 template <typename VType>
274  return Self(sqrt(c_[0]), sqrt(c_[1]));
275 }
276 
277 template <typename VType>
279  return Self(fabs(c_[0]), fabs(c_[1]));
280 }
281 
282 template <typename VType>
284  COMPILE_ASSERT(std::is_integral<VType>::value, use_Fabs_for_float_types);
285  COMPILE_ASSERT(static_cast<VType>(-1) == -1, type_must_be_signed);
286  COMPILE_ASSERT(sizeof(VType) <= sizeof(int), Abs_truncates_to_int);
287  return Self(abs(c_[0]), abs(c_[1]));
288 }
289 
290 template <typename VType>
292  return Self(floor(c_[0]), floor(c_[1]));
293 }
294 
295 
296 template <typename VType>
298  return Self(ceil(c_[0]), ceil(c_[1]));
299 }
300 
301 
302 template <typename VType>
304  return Self(rint(c_[0]), rint(c_[1]));
305 }
306 
307 template <typename VType>
309  return Vector2<int>(lrint(c_[0]), lrint(c_[1]));
310 }
311 
312 template <typename VType>
313 void Vector2<VType>::Clear() {
314  c_[1] = c_[0] = VType();
315 }
316 
317 template <typename VType>
318 bool Vector2<VType>::IsNaN() const {
319  return isnan(c_[0]) || isnan(c_[1]);
320 }
321 
322 template <typename VType>
324  return Self(MathUtil::NaN(), MathUtil::NaN());
325 }
326 
327 template <typename ScalarType, typename VType2>
328 Vector2<VType2> operator*(const ScalarType k, const Vector2<VType2> v) {
329  return Vector2<VType2>( k * v[0], k * v[1]);
330 }
331 
332 template <typename ScalarType, typename VType2>
333 Vector2<VType2> operator/(const ScalarType k, const Vector2<VType2> v) {
334  return Vector2<VType2>(k / v[0], k / v[1]);
335 }
336 
337 template <typename VType>
338 Vector2<VType> Max(const Vector2<VType> &v1, const Vector2<VType> &v2) {
339  return Vector2<VType>(max(v1[0], v2[0]), max(v1[1], v2[1]));
340 }
341 
342 template <typename VType>
343 Vector2<VType> Min(const Vector2<VType> &v1, const Vector2<VType> &v2) {
344  return Vector2<VType>(min(v1[0], v2[0]), min(v1[1], v2[1]));
345 }
346 
347 template <typename VType>
348 std::ostream &operator <<(std::ostream &out, const Vector2<VType> &va) {
349  out << "["
350  << va[0] << ", "
351  << va[1] << "]";
352  return out;
353 }
354 
355 // TODO(user): Vector2<T> does not actually satisfy the definition of a POD
356 // type even when T is a POD. Pretending that Vector2<T> is a POD probably
357 // won't cause any immediate problems, but eventually this should be fixed.
358 PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(Vector2);
359 
360 #endif // UTIL_MATH_VECTOR2_INL_H__