1// Copyright 2003 Google, Inc.
2// All Rights Reserved.
3//
4//
5// A simple class to handle vectors in 2D
6// The aim of this class is to be able to manipulate vectors in 2D
7// as naturally as possible and make calculations readable.
8// For that reason, the operators +, -, * are overloaded.
9// (Reading a = a + b*2 - c is much easier to read than
10// a = Sub(Add(a, Mul(b,2)),c) )
11// The code generated using this vector class is easily optimized by
12// the compiler and does not generate overhead compared to manually
13// writing the operations component by component
14// (e.g a.x = b.x + c.x; a.y = b.y + c.y...)
15//
16// Operator overload is not usually allowed, but in this case an
17// exemption has been granted by the C++ style committee.
18//
19// Please be careful about overflows when using those vectors with integer types
20// The calculations are carried with the same type as the vector's components
21// type. eg : if you are using uint8 as the base type, all values will be modulo
22// 256.
23// This feature is necessary to use the class in a more general framework with
24// VType != plain old data type.
25
26#ifndef UTIL_MATH_VECTOR2_INL_H__
27#define UTIL_MATH_VECTOR2_INL_H__
28
29#include "util/math/vector2.h"
30
31#include <math.h>
32#include "base/basictypes.h"
33#include "base/logging.h"
34#include "base/template_util.h"
35#include "base/type_traits.h"
36#include "util/math/mathutil.h"
37#include "util/math/vector3.h"
38#include "util/math/vector4.h"
39
40template <typename VType>
41Vector2<VType>::Vector2() {
42 Clear();
43}
44template <typename VType>
45Vector2<VType>::Vector2(const VType x, const VType y) {
46 c_[0] = x;
47 c_[1] = y;
48}
49template <typename VType>
50Vector2<VType>::Vector2(const Self &vb) {
51 c_[0] = vb.c_[0];
52 c_[1] = vb.c_[1];
53}
54template <typename VType>
55Vector2<VType>::Vector2(const Vector3<VType> &vb) {
56 c_[0] = vb.x();
57 c_[1] = vb.y();
58}
59template <typename VType>
60Vector2<VType>::Vector2(const Vector4<VType> &vb) {
61 c_[0] = vb.x();
62 c_[1] = vb.y();
63}
64
65template <typename VType> template <typename VType2>
66Vector2<VType> Vector2<VType>::Cast(const Vector2<VType2> &vb) {
67 return Self(static_cast<VType>(vb[0]),
68 static_cast<VType>(vb[1]));
69}
70
71template <typename VType>
72void Vector2<VType>::Set(const VType x, const VType y) {
73 c_[0] = x;
74 c_[1] = y;
75}
76
77template <typename VType>
78const Vector2<VType>& Vector2<VType>::operator=(const Self &vb) {
79 c_[0] = vb.c_[0];
80 c_[1] = vb.c_[1];
81 return (*this);
82}
83
84template <typename VType>
85Vector2<VType>& Vector2<VType>::operator+=(const Self &vb) {
86 c_[0] += vb.c_[0];
87 c_[1] += vb.c_[1];
88 return (*this);
89}
90
91template <typename VType>
92Vector2<VType>& Vector2<VType>::operator-=(const Self &vb) {
93 c_[0] -= vb.c_[0];
94 c_[1] -= vb.c_[1];
95 return (*this);
96}
97
98template <typename VType>
99Vector2<VType>& Vector2<VType>::operator*=(const VType k) {
100 c_[0] *= k;
101 c_[1] *= k;
102 return (*this);
103}
104
105template <typename VType>
106Vector2<VType>& Vector2<VType>::operator/=(const VType k) {
107 c_[0] /= k;
108 c_[1] /= k;
109 return (*this);
110}
111
112template <typename VType>
113Vector2<VType> Vector2<VType>::MulComponents(const Self &vb) const {
114 return Self(c_[0] * vb.c_[0], c_[1] * vb.c_[1]);
115}
116
117template <typename VType>
118Vector2<VType> Vector2<VType>::DivComponents(const Self &vb) const {
119 return Self(c_[0] / vb.c_[0], c_[1] / vb.c_[1]);
120}
121
122template <typename VType>
123Vector2<VType> Vector2<VType>::operator+(const Self &vb) const {
124 return Self(*this) += vb;
125}
126
127template <typename VType>
128Vector2<VType> Vector2<VType>::operator-(const Self &vb) const {
129 return Self(*this) -= vb;
130}
131
132template <typename VType>
133Vector2<VType> Vector2<VType>::operator-() const {
134 return Self(-c_[0], -c_[1]);
135}
136
137template <typename VType>
138VType Vector2<VType>::DotProd(const Self &vb) const {
139 return c_[0] * vb.c_[0] + c_[1] * vb.c_[1];
140}
141
142template <typename VType>
143Vector2<VType> Vector2<VType>::operator*(const VType k) const {
144 return Self(*this) *= k;
145}
146
147template <typename VType>
148Vector2<VType> Vector2<VType>::operator/(const VType k) const {
149 return Self(*this) /= k;
150}
151
152template <typename VType>
153VType Vector2<VType>::CrossProd(const Self &vb) const {
154 return c_[0] * vb.c_[1] - c_[1] * vb.c_[0];
155}
156
157template <typename VType>
158VType& Vector2<VType>::operator[](const int b) {
159 DCHECK(b >= 0);
160 DCHECK(b <= 1);
161 return c_[b];
162}
163
164template <typename VType>
165VType Vector2<VType>::operator[](const int b) const {
166 DCHECK(b >= 0);
167 DCHECK(b <= 1);
168 return c_[b];
169}
170
171template <typename VType>
172void Vector2<VType>::x(const VType &v) {
173 c_[0] = v;
174}
175
176template <typename VType>
177VType Vector2<VType>::x() const {
178 return c_[0];
179}
180
181template <typename VType>
182void Vector2<VType>::y(const VType &v) {
183 c_[1] = v;
184}
185
186template <typename VType>
187VType Vector2<VType>::y() const {
188 return c_[1];
189}
190
191
192
193template <typename VType>
194VType* Vector2<VType>::Data() {
195 return reinterpret_cast<VType*>(c_);
196}
197
198template <typename VType>
199const VType* Vector2<VType>::Data() const {
200 return reinterpret_cast<const VType*>(c_);
201}
202
203
204template <typename VType>
205VType Vector2<VType>::Norm2(void) const {
206 return c_[0]*c_[0] + c_[1]*c_[1];
207}
208
209
210template <typename VType>
211typename Vector2<VType>::FloatType Vector2<VType>::Norm(void) const {
212 return sqrt(Norm2());
213}
214
215template <typename VType>
216typename Vector2<VType>::FloatType Vector2<VType>::Angle(const Self &v) const {
217 return atan2(this->CrossProd(v), this->DotProd(v));
218}
219
220template <typename VType>
221Vector2<VType> Vector2<VType>::Normalize() const {
222 COMPILE_ASSERT(!base::is_integral<VType>::value, must_be_floating_point);
223 VType n = Norm();
224 if (n != 0) {
225 n = 1.0 / n;
226 }
227 return Self(*this) *= n;
228}
229
230template <typename VType>
231bool Vector2<VType>::operator==(const Self &vb) const {
232 return (c_[0] == vb.c_[0]) && (c_[1] == vb.c_[1]);
233}
234
235template <typename VType>
236bool Vector2<VType>::operator!=(const Self &vb) const {
237 return (c_[0] != vb.c_[0]) || (c_[1] != vb.c_[1]);
238}
239
240template <typename VType>
241bool Vector2<VType>::aequal(const Self &vb, FloatType margin) const {
242 return (fabs(c_[0]-vb.c_[0]) < margin) && (fabs(c_[1]-vb.c_[1]) < margin);
243}
244
245template <typename VType>
246bool Vector2<VType>::operator<(const Self &vb) const {
247 if ( c_[0] < vb.c_[0] ) return true;
248 if ( vb.c_[0] < c_[0] ) return false;
249 if ( c_[1] < vb.c_[1] ) return true;
250 return false;
251}
252
253template <typename VType>
254bool Vector2<VType>::operator>(const Self &vb) const {
255 return vb.operator<(*this);
256}
257
258template <typename VType>
259bool Vector2<VType>::operator<=(const Self &vb) const {
260 return !operator>(vb);
261}
262
263template <typename VType>
264bool Vector2<VType>::operator>=(const Self &vb) const {
265 return !operator<(vb);
266}
267
268template <typename VType>
269Vector2<VType> Vector2<VType>::Ortho() const {
270 return Self(-c_[1], c_[0]);
271}
272
273template <typename VType>
274Vector2<VType> Vector2<VType>::Sqrt() const {
275 return Self(sqrt(c_[0]), sqrt(c_[1]));
276}
277
278template <typename VType>
279Vector2<VType> Vector2<VType>::Fabs() const {
280 return Self(fabs(c_[0]), fabs(c_[1]));
281}
282
283template <typename VType>
284Vector2<VType> Vector2<VType>::Abs() const {
285 COMPILE_ASSERT(base::is_integral<VType>::value, use_Fabs_for_float_types);
286 COMPILE_ASSERT(static_cast<VType>(-1) == -1, type_must_be_signed);
287 COMPILE_ASSERT(sizeof(VType) <= sizeof(int), Abs_truncates_to_int);
288 return Self(abs(c_[0]), abs(c_[1]));
289}
290
291template <typename VType>
292Vector2<VType> Vector2<VType>::Floor() const {
293 return Self(floor(c_[0]), floor(c_[1]));
294}
295
296
297template <typename VType>
298Vector2<VType> Vector2<VType>::Ceil() const {
299 return Self(ceil(c_[0]), ceil(c_[1]));
300}
301
302
303template <typename VType>
304Vector2<VType> Vector2<VType>::FRound() const {
305 return Self(rint(c_[0]), rint(c_[1]));
306}
307
308template <typename VType>
309Vector2<int> Vector2<VType>::IRound() const {
310 return Vector2<int>(lrint(c_[0]), lrint(c_[1]));
311}
312
313template <typename VType>
314void Vector2<VType>::Clear() {
315 c_[1] = c_[0] = VType();
316}
317
318template <typename VType>
319bool Vector2<VType>::IsNaN() const {
320 return isnan(c_[0]) || isnan(c_[1]);
321}
322
323template <typename VType>
324Vector2<VType> Vector2<VType>::NaN() {
325 return Self(MathUtil::NaN(), MathUtil::NaN());
326}
327
328template <typename ScalarType, typename VType2>
329Vector2<VType2> operator*(const ScalarType k, const Vector2<VType2> v) {
330 return Vector2<VType2>( k * v[0], k * v[1]);
331}
332
333template <typename ScalarType, typename VType2>
334Vector2<VType2> operator/(const ScalarType k, const Vector2<VType2> v) {
335 return Vector2<VType2>(k / v[0], k / v[1]);
336}
337
338template <typename VType>
339Vector2<VType> Max(const Vector2<VType> &v1, const Vector2<VType> &v2) {
340 return Vector2<VType>(max(v1[0], v2[0]), max(v1[1], v2[1]));
341}
342
343template <typename VType>
344Vector2<VType> Min(const Vector2<VType> &v1, const Vector2<VType> &v2) {
345 return Vector2<VType>(min(v1[0], v2[0]), min(v1[1], v2[1]));
346}
347
348template <typename VType>
349std::ostream &operator <<(std::ostream &out, const Vector2<VType> &va) {
350 out << "["
351 << va[0] << ", "
352 << va[1] << "]";
353 return out;
354}
355
356// TODO(user): Vector2<T> does not actually satisfy the definition of a POD
357// type even when T is a POD. Pretending that Vector2<T> is a POD probably
358// won't cause any immediate problems, but eventually this should be fixed.
359PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(Vector2);
360
361#endif // UTIL_MATH_VECTOR2_INL_H__
362