vector3-inl.h
1 // Copyright 2003 Google, Inc.
2 // All Rights Reserved.
3 //
4 //
5 // A simple class to handle vectors in 3D
6 // The aim of this class is to be able to manipulate vectors in 3D
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_VECTOR3_INL_H__
27 #define UTIL_MATH_VECTOR3_INL_H__
28 
29 #include "util/math/vector3.h"
30 
31 #include <algorithm>
32 using std::min;
33 using std::max;
34 using std::swap;
35 using std::reverse;
36 
37 #include <math.h>
38 #include "base/integral_types.h"
39 
40 #include "base/type_traits.h"
41 #include "util/math/mathutil.h"
42 #include "util/math/vector2.h"
43 #include "util/math/vector4.h"
44 
45 template <typename VType>
47  Clear();
48 }
49 
50 template <typename VType>
51 Vector3<VType>::Vector3(const VType x, const VType y, const VType z) {
52  c_[0] = x;
53  c_[1] = y;
54  c_[2] = z;
55 }
56 
57 template <typename VType>
58 Vector3<VType>::Vector3(const Vector2<VType> &vb, VType z) {
59  c_[0] = vb.x();
60  c_[1] = vb.y();
61  c_[2] = z;
62 }
63 
64 template <typename VType>
65 Vector3<VType>::Vector3(const Self &vb) {
66  c_[0] = vb.c_[0];
67  c_[1] = vb.c_[1];
68  c_[2] = vb.c_[2];
69 }
70 
71 template <typename VType>
73  c_[0] = vb.x();
74  c_[1] = vb.y();
75  c_[2] = vb.z();
76 }
77 
78 template <typename VType> template <typename VType2>
80  return Self(VType(vb[0]),
81  VType(vb[1]),
82  VType(vb[2]));
83 }
84 
85 template <typename VType>
86 bool Vector3<VType>::operator==(const Self& vb) const {
87  return (c_[0] == vb.c_[0]) && (c_[1] == vb.c_[1]) && (c_[2] == vb.c_[2]);
88 }
89 
90 template <typename VType>
91 bool Vector3<VType>::operator!=(const Self& vb) const {
92  return (c_[0] != vb.c_[0]) || (c_[1] != vb.c_[1]) || (c_[2] != vb.c_[2]);
93 }
94 
95 template <typename VType>
96 bool Vector3<VType>::aequal(const Self &vb, FloatType margin) const {
97  return (fabs(c_[0] - vb.c_[0]) < margin)
98  && (fabs(c_[1] - vb.c_[1]) < margin)
99  && (fabs(c_[2] - vb.c_[2]) < margin);
100 }
101 
102 template <typename VType>
103 bool Vector3<VType>::operator<(const Self &vb) const {
104  if ( c_[0] < vb.c_[0] ) return true;
105  if ( vb.c_[0] < c_[0] ) return false;
106  if ( c_[1] < vb.c_[1] ) return true;
107  if ( vb.c_[1] < c_[1] ) return false;
108  if ( c_[2] < vb.c_[2] ) return true;
109  return false;
110 }
111 
112 template <typename VType>
113 bool Vector3<VType>::operator>(const Self &vb) const {
114  return vb.operator<(*this);
115 }
116 
117 template <typename VType>
118 bool Vector3<VType>::operator<=(const Self &vb) const {
119  return !operator>(vb);
120 }
121 
122 template <typename VType>
123 bool Vector3<VType>::operator>=(const Self &vb) const {
124  return !operator<(vb);
125 }
126 
127 template <typename VType>
128 void Vector3<VType>::Set(const VType x, const VType y, const VType z) {
129  c_[0] = x;
130  c_[1] = y;
131  c_[2] = z;
132 }
133 
134 template <typename VType>
135 Vector3<VType>& Vector3<VType>::operator=(const Self& vb) {
136  c_[0] = vb.c_[0];
137  c_[1] = vb.c_[1];
138  c_[2] = vb.c_[2];
139  return (*this);
140 }
141 
142 template <typename VType>
144  c_[0] += vb.c_[0];
145  c_[1] += vb.c_[1];
146  c_[2] += vb.c_[2];
147  return (*this);
148 }
149 
150 template <typename VType>
152  c_[0] -= vb.c_[0];
153  c_[1] -= vb.c_[1];
154  c_[2] -= vb.c_[2];
155  return (*this);
156 }
157 
158 template <typename VType>
160  c_[0] *= k;
161  c_[1] *= k;
162  c_[2] *= k;
163  return (*this);
164 }
165 
166 template <typename VType>
168  c_[0] /= k;
169  c_[1] /= k;
170  c_[2] /= k;
171  return (*this);
172 }
173 
174 template <typename VType>
175 Vector3<VType> Vector3<VType>::MulComponents(const Self &vb) const {
176  return Self(c_[0] * vb.c_[0], c_[1] * vb.c_[1], c_[2] * vb.c_[2]);
177 }
178 
179 template <typename VType>
180 Vector3<VType> Vector3<VType>::DivComponents(const Self &vb) const {
181  return Self(c_[0] / vb.c_[0], c_[1] / vb.c_[1], c_[2] / vb.c_[2]);
182 }
183 
184 template <typename VType>
185 Vector3<VType> Vector3<VType>::operator+(const Self &vb) const {
186  return Self(*this) += vb;
187 }
188 
189 template <typename VType>
190 Vector3<VType> Vector3<VType>::operator-(const Self &vb) const {
191  return Self(*this) -= vb;
192 }
193 
194 template <typename VType>
195 VType Vector3<VType>::DotProd(const Self &vb) const {
196  return c_[0]*vb.c_[0] + c_[1]*vb.c_[1] + c_[2]*vb.c_[2];
197 }
198 
199 template <typename VType>
200 Vector3<VType> Vector3<VType>::operator*(const VType k) const {
201  return Self(*this) *= k;
202 }
203 
204 template <typename VType>
205 Vector3<VType> Vector3<VType>::operator/(const VType k) const {
206  return Self(*this) /= k;
207 }
208 
209 template <typename VType>
210 Vector3<VType> Vector3<VType>::CrossProd(const Self& vb) const {
211  return Self( c_[1] * vb.c_[2] - c_[2] * vb.c_[1],
212  c_[2] * vb.c_[0] - c_[0] * vb.c_[2],
213  c_[0] * vb.c_[1] - c_[1] * vb.c_[0]);
214 }
215 
216 template <typename VType>
217 VType& Vector3<VType>::operator[](const int b) {
218  DCHECK(b >=0);
219  DCHECK(b <=2);
220  return c_[b];
221 }
222 
223 template <typename VType>
224 VType Vector3<VType>::operator[](const int b) const {
225  DCHECK(b >=0);
226  DCHECK(b <=2);
227  return c_[b];
228 }
229 
230 template <typename VType>
231 void Vector3<VType>::x(const VType &v) {
232  c_[0] = v;
233 }
234 
235 template <typename VType>
236 VType Vector3<VType>::x() const {
237  return c_[0];
238 }
239 
240 template <typename VType>
241 void Vector3<VType>::y(const VType &v) {
242  c_[1] = v;
243 }
244 
245 template <typename VType>
246 VType Vector3<VType>::y() const {
247  return c_[1];
248 }
249 
250 template <typename VType>
251 void Vector3<VType>::z(const VType &v) {
252  c_[2] = v;
253 }
254 
255 template <typename VType>
256 VType Vector3<VType>::z() const {
257  return c_[2];
258 }
259 
260 template <typename VType>
261 VType* Vector3<VType>::Data() {
262  return reinterpret_cast<VType*>(c_);
263 }
264 
265 template <typename VType>
266 const VType* Vector3<VType>::Data() const {
267  return reinterpret_cast<const VType*>(c_);
268 }
269 
270 template <typename VType>
271 VType Vector3<VType>::Norm2(void) const {
272  return c_[0]*c_[0] + c_[1]*c_[1] + c_[2]*c_[2];
273 }
274 
275 template <typename VType>
276 typename Vector3<VType>::FloatType Vector3<VType>::Norm(void) const {
277  return sqrt(Norm2());
278 }
279 
280 template <typename VType>
282  COMPILE_ASSERT(!std::is_integral<VType>::value, must_be_floating_point);
283  VType n = Norm();
284  if (n != 0) {
285  n = 1.0 / n;
286  }
287  return Self(*this) *= n;
288 }
289 
290 template <typename VType>
292  int k = LargestAbsComponent() - 1;
293  if (k < 0) k = 2;
294  Self temp;
295  temp[k] = 1;
296  return (this->CrossProd(temp)).Normalize();
297 }
298 
299 template <typename VType>
301  Self temp = Fabs();
302  if (temp[0] > temp[1]) {
303  if (temp[0] > temp[2]) {
304  return 0;
305  } else {
306  return 2;
307  }
308  } else {
309  if (temp[1] > temp[2]) {
310  return 1;
311  } else {
312  return 2;
313  }
314  }
315 }
316 
317 template <typename VType>
319  Vector3<int> temp(0, 1, 2);
320  if (c_[temp[0]] > c_[temp[1]]) swap(temp[0], temp[1]);
321  if (c_[temp[1]] > c_[temp[2]]) swap(temp[1], temp[2]);
322  if (c_[temp[0]] > c_[temp[1]]) swap(temp[0], temp[1]);
323  return temp;
324 }
325 
326 template <typename VType>
327 typename Vector3<VType>::FloatType Vector3<VType>::Angle(const Self &va) const {
328  return atan2(this->CrossProd(va).Norm(), this->DotProd(va));
329 }
330 
331 template <typename VType>
333  return Self(sqrt(c_[0]), sqrt(c_[1]), sqrt(c_[2]));
334 }
335 
336 template <typename VType>
338  return Self(fabs(c_[0]), fabs(c_[1]), fabs(c_[2]));
339 }
340 
341 template <typename VType>
343  COMPILE_ASSERT(std::is_integral<VType>::value, use_Fabs_for_float_types);
344  COMPILE_ASSERT(static_cast<VType>(-1) == -1, type_must_be_signed);
345  COMPILE_ASSERT(sizeof(VType) <= sizeof(int), Abs_truncates_to_int);
346  return Self(abs(c_[0]), abs(c_[1]), abs(c_[2]));
347 }
348 
349 template <typename VType>
351  return Self(floor(c_[0]), floor(c_[1]), floor(c_[2]));
352 }
353 
354 template <typename VType>
356  return Self(ceil(c_[0]), ceil(c_[1]), ceil(c_[2]));
357 }
358 
359 template <typename VType>
361  return Self(rint(c_[0]), rint(c_[1]), rint(c_[2]));
362 }
363 
364 template <typename VType>
366  return Vector3<int>(lrint(c_[0]), lrint(c_[1]), lrint(c_[2]));
367 }
368 
369 template <typename VType>
370 void Vector3<VType>::Clear() {
371  c_[2] = c_[1] = c_[0] = VType();
372 }
373 
374 template <typename VType>
375 bool Vector3<VType>::IsNaN() const {
376  return isnan(c_[0]) || isnan(c_[1]) || isnan(c_[2]);
377 }
378 
379 template <typename VType>
381  return Self(MathUtil::NaN(), MathUtil::NaN(), MathUtil::NaN());
382 }
383 
384 template <typename VType>
385 Vector3<VType> operator-(const Vector3<VType> &vb) {
386  return Vector3<VType>(-vb[0], -vb[1], -vb[2]);
387 }
388 
389 template <typename ScalarType, typename VType>
390 Vector3<VType> operator*(const ScalarType k, const Vector3<VType> &v) {
391  return Vector3<VType>(k*v[0], k*v[1], k*v[2]);
392 }
393 
394 template <typename ScalarType, typename VType>
395 Vector3<VType> operator/(const ScalarType k, const Vector3<VType> &v) {
396  return Vector3<VType>(k/v[0], k/v[1], k/v[2]);
397 }
398 
399 template <typename VType>
400 Vector3<VType> Max(const Vector3<VType> &v1, const Vector3<VType> &v2) {
401  return Vector3<VType>(max(v1[0], v2[0]),
402  max(v1[1], v2[1]),
403  max(v1[2], v2[2]));
404 }
405 
406 template <typename VType>
407 Vector3<VType> Min(const Vector3<VType> &v1, const Vector3<VType> &v2) {
408  return Vector3<VType>(min(v1[0], v2[0]),
409  min(v1[1], v2[1]),
410  min(v1[2], v2[2]));
411 }
412 
413 template <typename VType>
414 std::ostream &operator <<(std::ostream &out, const Vector3<VType> &va) {
415  out << "["
416  << va[0] << ", "
417  << va[1] << ", "
418  << va[2] << "]";
419  return out;
420 }
421 
422 // TODO(user): Vector3<T> does not actually satisfy the definition of a POD
423 // type even when T is a POD. Pretending that Vector3<T> is a POD probably
424 // won't cause any immediate problems, but eventually this should be fixed.
425 PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(Vector3);
426 
427 #endif // UTIL_MATH_VECTOR3_INL_H__