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