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