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