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