vector3.h
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>
13 #include <type_traits>
14 
15 using std::ostream;
16  // NOLINT(readability/streams)
17 #include "base/integral_types.h"
18 
19 template <typename VType> class Vector3;
20 // TODO(user): Look into creating conversion operators to remove the
21 // need to forward-declare Vector2 and Vector4.
22 template <typename VType> class Vector2;
23 template <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.
29 template <typename VType>
30 class 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 std::conditional<std::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
164 template <typename VType>
165 Vector3<VType> operator-(const Vector3<VType> &vb);
166 // multiply by a scalar
167 template <typename ScalarType, typename VType>
168 Vector3<VType> operator*(const ScalarType k, const Vector3<VType> &v);
169 // perform k /
170 template <typename ScalarType, typename VType>
171 Vector3<VType> operator/(const ScalarType k, const Vector3<VType> &v);
172 // return a vector containing the max of v1 and v2 component by component
173 template <typename VType>
174 Vector3<VType> Max(const Vector3<VType> &v1, const Vector3<VType> &v2);
175 // return a vector containing the min of v1 and v2 component by component
176 template <typename VType>
177 Vector3<VType> Min(const Vector3<VType> &v1, const Vector3<VType> &v2);
178 // debug printing
179 template <typename VType>
180 std::ostream &operator <<(std::ostream &out, // NOLINT
181  const Vector3<VType> &va);
182 
183 // TODO(user): Declare extern templates for these types.
184 typedef Vector3<uint8> Vector3_b;
185 typedef Vector3<int> Vector3_i;
186 typedef Vector3<float> Vector3_f;
187 typedef Vector3<double> Vector3_d;
188 
189 #endif // UTIL_MATH_VECTOR3_H__