1// Copyright 2003 Google, Inc.
2// All Rights Reserved.
3//
4//
5// A simple class to handle vectors in 3D
6// See the vector3-inl.h file for more details
7
8
9#ifndef UTIL_MATH_VECTOR3_H__
10#define UTIL_MATH_VECTOR3_H__
11
12#include <iostream>
13using std::ostream;
14using std::cout;
15using std::endl;
16 // NOLINT(readability/streams)
17#include "base/basictypes.h"
18
19template <typename VType> class Vector3;
20// TODO(user): Look into creating conversion operators to remove the
21// need to forward-declare Vector2 and Vector4.
22template <typename VType> class Vector2;
23template <typename VType> class Vector4;
24
25// Template class for 3D vectors.
26// All definitions for these functions are in vector3-inl.h. That header will
27// need to be included in order to actually use this class. This class can be
28// regarded to only forward-declare Vector3.
29template <typename VType>
30class Vector3 {
31 private:
32 VType c_[3];
33
34 // FloatType is the type returned by Norm() and Angle(). These methods are
35 // special because they return floating-point values even when VType is an
36 // integer.
37 typedef typename base::if_<base::is_integral<VType>::value,
38 double, VType>::type FloatType;
39
40 public:
41 typedef Vector3<VType> Self;
42 typedef VType BaseType;
43 // Create a new vector (0,0,0)
44 Vector3();
45 // Create a new vector (x,y,z)
46 Vector3(const VType x, const VType y, const VType z);
47 // Create a new 3D vector using the two first coordinates of a 2D vectors
48 // and an additional z argument.
49 explicit Vector3(const Vector2<VType> &vb, VType z);
50 // Create a new copy of the vector vb
51 Vector3(const Self &vb);
52 // Keep only the three first coordinates of the 4D vector vb
53 explicit Vector3(const Vector4<VType> &vb);
54 // Convert from another vector type
55 template <typename VType2>
56 static Self Cast(const Vector3<VType2> &vb);
57 // Compare two vectors, return true if all their components are equal
58 bool operator==(const Self& vb) const;
59 bool operator!=(const Self& vb) const;
60 // Compare two vectors, return true if all their components are within
61 // a difference of margin.
62 bool aequal(const Self &vb, FloatType margin) const;
63 // Compare two vectors, these comparisons are mostly for interaction
64 // with STL.
65 bool operator<(const Self &vb) const;
66 bool operator>(const Self &vb) const;
67 bool operator<=(const Self &vb) const;
68 bool operator>=(const Self &vb) const;
69
70 // Return the size of the vector
71 static int Size() { return 3; }
72 // Modify the coordinates of the current vector
73 void Set(const VType x, const VType y, const VType z);
74 Self& operator=(const Self& vb);
75 // Add two vectors, component by component
76 Self& operator+=(const Self &vb);
77 // Subtract two vectors, component by component
78 Self& operator-=(const Self &vb);
79 // Multiply a vector by a scalar
80 Self& operator*=(const VType k);
81 // Divide a vector by a scalar
82 Self& operator/=(const VType k);
83 // Multiply two vectors component by component
84 Self MulComponents(const Self &vb) const;
85 // Divide two vectors component by component
86 Self DivComponents(const Self &vb) const;
87 // Add two vectors, component by component
88 Self operator+(const Self &vb) const;
89 // Subtract two vectors, component by component
90 Self operator-(const Self &vb) const;
91 // Dot product. Be aware that if VType is an integer type, the high bits of
92 // the result are silently discarded.
93 VType DotProd(const Self &vb) const;
94 // Multiplication by a scalar
95 Self operator*(const VType k) const;
96 // Divide by a scalar
97 Self operator/(const VType k) const;
98 // Cross product. Be aware that if VType is an integer type, the high bits
99 // of the result are silently discarded.
100 Self CrossProd(const Self& vb) const;
101 // Access component #b for read/write operations
102 VType& operator[](const int b);
103 // Access component #b for read only operations
104 VType operator[](const int b) const;
105 // Labeled Accessor methods.
106 void x(const VType &v);
107 VType x() const;
108 void y(const VType &v);
109 VType y() const;
110 void z(const VType &v);
111 VType z() const;
112 // return a pointer to the data array for interface with other libraries
113 // like opencv
114 VType* Data();
115 const VType* Data() const;
116 // Return the squared Euclidean norm of the vector. Be aware that if VType
117 // is an integer type, the high bits of the result are silently discarded.
118 VType Norm2(void) const;
119 // Return the Euclidean norm of the vector. Note that if VType is an
120 // integer type, the return value is correct only if the *squared* norm does
121 // not overflow VType.
122 FloatType Norm(void) const;
123 // Return a normalized version of the vector if the norm of the
124 // vector is not 0. Not to be used with integer types.
125 Self Normalize() const;
126 // return a vector orthogonal to this one
127 Self Ortho() const;
128 // return the index of the largest component (fabs)
129 int LargestAbsComponent() const;
130 // return the index of the smallest, median ,largest component of the vector
131 Vector3<int> ComponentOrder() const;
132 // return the angle between two vectors in radians
133 FloatType Angle(const Self &va) const;
134 // take the sqrt of each component and return a vector containing those values
135 Self Sqrt() const;
136 // take the fabs of each component and return a vector containing those values
137 Self Fabs() const;
138 // Take the absolute value of each component and return a vector containing
139 // those values. This method should only be used when VType is a signed
140 // integer type that is not wider than "int".
141 Self Abs() const;
142 // take the floor of each component and return a vector containing
143 // those values
144 Self Floor() const;
145 // take the ceil of each component and return a vector containing those values
146 Self Ceil() const;
147 // take the round of each component and return a vector containing those
148 // values
149 Self FRound() const;
150 // take the round of each component and return an integer vector containing
151 // those values
152 Vector3<int> IRound() const;
153 // Reset all the coordinates of the vector to 0
154 void Clear();
155
156 // return true if one of the components is not a number
157 bool IsNaN() const;
158
159 // return an invalid floating point vector
160 static Self NaN();
161};
162
163// Change the sign of the components of a vector
164template <typename VType>
165Vector3<VType> operator-(const Vector3<VType> &vb);
166// multiply by a scalar
167template <typename ScalarType, typename VType>
168Vector3<VType> operator*(const ScalarType k, const Vector3<VType> &v);
169// perform k /
170template <typename ScalarType, typename VType>
171Vector3<VType> operator/(const ScalarType k, const Vector3<VType> &v);
172// return a vector containing the max of v1 and v2 component by component
173template <typename VType>
174Vector3<VType> Max(const Vector3<VType> &v1, const Vector3<VType> &v2);
175// return a vector containing the min of v1 and v2 component by component
176template <typename VType>
177Vector3<VType> Min(const Vector3<VType> &v1, const Vector3<VType> &v2);
178// debug printing
179template <typename VType>
180std::ostream &operator <<(std::ostream &out, // NOLINT
181 const Vector3<VType> &va);
182
183// TODO(user): Declare extern templates for these types.
184typedef Vector3<uint8> Vector3_b;
185typedef Vector3<int> Vector3_i;
186typedef Vector3<float> Vector3_f;
187typedef Vector3<double> Vector3_d;
188
189#endif // UTIL_MATH_VECTOR3_H__
190