OGLplus (0.52.0) a C++ wrapper for OpenGL

vector.hpp
Go to the documentation of this file.
1 
12 #pragma once
13 #ifndef OGLPLUS_VECTOR_1107121519_HPP
14 #define OGLPLUS_VECTOR_1107121519_HPP
15 
16 #include <oglplus/config/compiler.hpp>
17 #include <oglplus/utils/nothing.hpp>
18 #include <oglplus/fwd.hpp>
19 #include <cassert>
20 #include <cmath>
21 #include <cstddef>
22 #include <algorithm>
23 #include <type_traits>
24 
25 namespace oglplus {
26 
27 template <typename T, std::size_t Rows, std::size_t Cols>
28 class Matrix;
29 
30 template<typename T, std::size_t R, std::size_t C>
31 T At(const Matrix<T, R, C>&, std::size_t r, std::size_t c);
32 
33 template <typename T, std::size_t N>
34 class Vector;
35 
36 #if OGLPLUS_DOCUMENTATION_ONLY || defined(GL_INT)
37 
41 typedef Vector<GLint, 1> Vec1i;
42 
44 
48 
50 
54 
56 
60 #endif
61 
62 #if OGLPLUS_DOCUMENTATION_ONLY || defined(GL_FLOAT)
63 
68 
70 
74 
76 
80 
82 
86 #endif
87 
88 #if OGLPLUS_DOCUMENTATION_ONLY || defined(GL_DOUBLE)
89 
94 
96 
100 
102 
106 
108 
112 #endif
113 
114 
116 template <typename T, std::size_t N>
118 {
119 protected:
120  T _elem[N];
121 
122  VectorBase(oglplus::Nothing)
123  { }
125  VectorBase(void)
126  {
127  std::fill(_elem, _elem+N, T(0));
128  }
130  VectorBase(T v)
131  {
132  std::fill(_elem, _elem+N, v);
133  }
135  VectorBase(const T (&v)[N])
136  {
137  std::copy(v, v+N, _elem);
138  }
140  VectorBase(const T* v, std::size_t n)
141  {
142  OGLPLUS_FAKE_USE(n);
143  assert(n >= N);
145  std::copy(v, v+N, _elem);
146  }
147 
148  VectorBase(const T* v, std::size_t n, T def)
149  {
150  if(n > N) n = N;
151  std::copy(v, v+n, _elem);
152  std::fill(_elem+n, _elem+N, def);
153  }
154 
155  template <std::size_t M>
156  VectorBase(
157  const VectorBase<T, M>& v,
158  typename std::enable_if<(N < M)>::type* = nullptr
159  )
160  {
161  std::copy(v.Data(), v.Data()+N, _elem);
162  }
163 
164  template <typename U, std::size_t M>
165  VectorBase(
166  const VectorBase<U, M>& v,
167  typename std::enable_if<
168  (N <= M) && (!std::is_same<T, U>::value)
169  >::type* = nullptr
170  )
171  {
172  for(std::size_t i=0; i!=N; ++i)
173  _elem[i] = T(v.At(i));
174  }
175 
176  explicit VectorBase(const Matrix<T, 1, N>& matrix)
177  {
178  for(std::size_t i=0; i!=N; ++i)
179  _elem[i] = At(matrix, 0, i);
180  }
181 
182  template <std::size_t M>
183  explicit VectorBase(
184  const Matrix<T, M, 1>& matrix,
185  typename std::enable_if<M != 1 && M == N, void>::type* = nullptr
186  )
187  {
188  for(std::size_t i=0; i!=N; ++i)
189  _elem[i] = At(matrix, i, 0);
190  }
191 public:
192  struct Unit_ { };
194 #if !OGLPLUS_NO_DEFAULTED_FUNCTIONS
195  VectorBase(const VectorBase&) = default;
196 
197  VectorBase(VectorBase&&) = default;
198 
199  VectorBase& operator = (const VectorBase&) = default;
200 
201  VectorBase& operator = (VectorBase&&) = default;
202 #endif
203 
205  static std::size_t Size(void)
206  {
207  return N;
208  }
209 
211  T* Data(void)
212  {
213  return this->_elem;
214  }
215 
217  const T* Data(void) const
218  {
219  return this->_elem;
220  }
223 
226  T At(std::size_t i) const
227  {
228  assert(i < N);
229  return _elem[i];
230  }
233 
236  T At(std::size_t i, T fallback) const
237  {
238  if(i < N) return _elem[i];
239  else return fallback;
240  }
241 
246  T& operator [](std::size_t i)
247  {
248  assert(i < N);
249  return _elem[i];
250  }
251 
253 
256  const T& operator [](std::size_t i) const
257  {
258  assert(i < N);
259  return _elem[i];
260  }
263  friend bool Equal(const VectorBase& a, const VectorBase& b)
264  {
265  for(std::size_t i=0; i!=N; ++i)
266  if(a._elem[i] != b._elem[i])
267  return false;
268  return true;
269  }
270 
272  void Add(const VectorBase& v)
273  {
274  for(std::size_t i=0; i!=N; ++i)
275  _elem[i] += v._elem[i];
276  }
277 
279  void Subtract(const VectorBase& v)
280  {
281  for(std::size_t i=0; i!=N; ++i)
282  _elem[i] -= v._elem[i];
283  }
284 
286  void Multiply(T v)
287  {
288  for(std::size_t i=0; i!=N; ++i)
289  _elem[i] *= v;
290  }
291 
293  void Multiply(const VectorBase& that)
294  {
295  for(std::size_t i=0; i!=N; ++i)
296  _elem[i] *= that._elem[i];
297  }
298 
300  void Divide(T v)
301  {
302  for(std::size_t i=0; i!=N; ++i)
303  _elem[i] /= v;
304  }
305 
307  void Divide(const VectorBase& that)
308  {
309  for(std::size_t i=0; i!=N; ++i)
310  _elem[i] /= that._elem[i];
311  }
312 
314  T Length(void) const
315  {
316  return std::sqrt(DotProduct(*this, *this));
317  }
318 
320  bool IsNormal(T eps = T(0)) const
321  {
322  return std::abs(DotProduct(*this, *this) - T(1)) <= eps;
323  }
326  void Normalize(void)
327  {
328  T l = Length();
329  if(l != T(0) && l != T(1))
330  Multiply(T(1) / l);
331  }
332 
334  static T DotProduct(const VectorBase& a, const VectorBase& b)
335  {
336  T result = (a._elem[0] * b._elem[0]);
337  for(std::size_t i=1; i!=N; ++i)
338  result += (a._elem[i] * b._elem[i]);
339  return result;
340  }
341 };
342 
343 
344 #include <oglplus/math/vector_1.ipp>
345 #include <oglplus/math/vector_2.ipp>
346 #include <oglplus/math/vector_3.ipp>
347 #include <oglplus/math/vector_4.ipp>
349 #if OGLPLUS_DOCUMENTATION_ONLY || !OGLPLUS_NO_VARIADIC_TEMPLATES
350 #include <oglplus/math/vector_n.ipp>
351 #endif
352 
353 #include <oglplus/math/vector_swizzle.ipp>
354 
355 template <typename T, std::size_t N>
356 inline const T* Data(const Vector<T, N>& a)
357 {
358  return a.Data();
359 }
360 
361 template <typename T, std::size_t N>
362 inline std::size_t Size(const Vector<T, N>&)
363 {
364  return N;
365 }
366 
367 template <typename T, std::size_t N>
368 inline T At(const Vector<T, N>& a, std::size_t i)
369 {
370  return a.At(i);
371 }
372 
373 template <typename T, std::size_t N>
374 inline T At(const Vector<T, N>& a, std::size_t i, T fallback)
375 {
376  return a.At(i, fallback);
377 }
378 
379 template <typename T, std::size_t N>
380 inline Vector<T, 1> Extract(
381  const Vector<T, N>& a,
382  std::size_t d0
383 )
384 {
385  return Vector<T, 1>(a[d0]);
386 }
387 
388 template <typename T, std::size_t N>
389 inline Vector<T, 2> Extract(
390  const Vector<T, N>& a,
391  std::size_t d0,
392  std::size_t d1
393 )
394 {
395  return Vector<T, 2>(a[d0], a[d1]);
396 }
397 
398 template <typename T, std::size_t N>
399 inline Vector<T, 3> Extract(
400  const Vector<T, N>& a,
401  std::size_t d0,
402  std::size_t d1,
403  std::size_t d2
404 )
405 {
406  return Vector<T, 3>(a[d0], a[d1], a[d2]);
407 }
408 
409 template <typename T, std::size_t N>
410 inline Vector<T, 4> Extract(
411  const Vector<T, N>& a,
412  std::size_t d0,
413  std::size_t d1,
414  std::size_t d2,
415  std::size_t d3
416 )
417 {
418  return Vector<T, 4>(a[d0], a[d1], a[d2], a[d3]);
419 }
420 
421 template <typename T, std::size_t N>
422 inline T Dot(const Vector<T, N>& a, const Vector<T, N>& b)
423 {
424  return Vector<T, N>::DotProduct(a, b);
425 }
426 
427 template <typename T, std::size_t N>
428 inline T Length(const Vector<T, N>& a)
429 {
430  return std::sqrt(Dot(a, a));
431 }
432 
433 
434 template <typename T, std::size_t N>
435 inline T Distance(const Vector<T, N>& a, const Vector<T, N>& b)
436 {
437  return Length(Subtracted(a, b));
438 }
439 
440 template <typename T, std::size_t N>
441 inline Vector<T, N> Normalized(Vector<T, N> a)
442 {
443  T l = Length(a);
444  if(l != T(0) && l != T(1))
445  a = Multiplied(a, T(1) / l);
446  return a;
447 }
448 
449 template <typename T>
450 inline Vector<T, 2> Perpendicular(const Vector<T, 2>& a)
451 {
452  return Vector<T, 2>(-a[1], a[0]);
453 }
454 
455 template <typename T>
456 inline Vector<T, 3> Cross(const Vector<T, 3>& a, const Vector<T, 3>& b)
457 {
458  return Vector<T, 3>(
459  a[1] * b[2] - a[2] * b[1],
460  a[2] * b[0] - a[0] * b[2],
461  a[0] * b[1] - a[1] * b[0]
462  );
463 }
464 
465 template <typename T, std::size_t N>
466 inline bool operator == (const Vector<T, N>& a, const Vector<T, N>& b)
467 {
468  return Equal(a, b);
469 }
470 
471 template <typename T, std::size_t N>
472 inline bool operator != (const Vector<T, N>& a, const Vector<T, N>& b)
473 {
474  return !Equal(a, b);
475 }
476 
477 template <typename T, std::size_t N>
478 inline Vector<T, N> operator + (const Vector<T, N>& v)
479 {
480  return v;
481 }
482 
483 template <typename T, std::size_t N>
484 inline Vector<T, N> operator - (const Vector<T, N>& v)
485 {
486  return Negated(v);
487 }
488 
489 template <typename T, std::size_t N>
490 inline Vector<T, N> operator + (const Vector<T, N>& a, const Vector<T, N>& b)
491 {
492  return Added(a, b);
493 }
494 
495 template <typename T, std::size_t N>
496 inline Vector<T, N> operator - (const Vector<T, N>& a, const Vector<T, N>& b)
497 {
498  return Subtracted(a, b);
499 }
500 
501 template <typename T, typename V, std::size_t N>
502 inline typename std::enable_if<
503  std::is_convertible<V, T>::value,
505 >::type operator * (const Vector<T, N>& a, V v)
506 {
507  return Multiplied(a, T(v));
508 }
509 
510 template <typename T, typename V, std::size_t N>
511 inline typename std::enable_if<
512  std::is_convertible<V, T>::value,
513  Vector<T, N>
514 >::type operator * (V v, const Vector<T, N>& a)
515 {
516  return Multiplied(a, T(v));
517 }
518 
519 
520 template <typename T, typename V, std::size_t N>
521 inline typename std::enable_if<
522  std::is_convertible<V, T>::value,
523  Vector<T, N>
524 >::type operator / (const Vector<T, N>& a, V v)
525 {
526  return Divided(a, v);
527 }
528 
529 template <typename T, std::size_t N, std::size_t Cols>
530 inline Vector<T, Cols> operator * (
531  const Vector<T, N>& v,
532  const Matrix<T, N, Cols>& m
533 )
534 {
535  T tmp[Cols];
536  for(std::size_t c=0; c!=Cols; ++c)
537  {
538  tmp[c] = T(0);
539  for(std::size_t r=0; r!=N; ++r)
540  {
541  tmp[c] += v.At(r) * m.At(r, c);
542  }
543  }
544  return Vector<T, Cols>(tmp);
545 }
546 
547 template <typename T, std::size_t N, std::size_t Rows>
548 inline Vector<T, Rows> operator * (
549  const Matrix<T, Rows, N>& m,
550  const Vector<T, N>& v
551 )
552 {
553  T tmp[Rows];
554  for(std::size_t r=0; r!=Rows; ++r)
555  {
556  tmp[r] = T(0);
557  for(std::size_t c=0; c!=N; ++c)
558  {
559  tmp[r] += m.At(r, c) * v.At(c);
560  }
561  }
562  return Vector<T, Rows>(tmp);
563 }
564 
565 
566 } // namespace oglplus
567 
568 #endif // include guard
Vector< GLfloat, 4 > Vec4f
4D float vector
Definition: vector.hpp:85
friend bool Equal(const VectorBase &a, const VectorBase &b)
Equality comparison.
Definition: vector.hpp:263
Common base class for vectors.
Definition: vector.hpp:117
Vector< GLdouble, 1 > Vec1d
1D double-precision (degenerate) vector
Definition: vector.hpp:93
T * Data(void)
Pointer to the components of this vector.
Definition: vector.hpp:211
Vector< GLint, 3 > Vec3i
3D int vector
Definition: vector.hpp:53
Vector< GLfloat, 2 > Vec2f
2D float vector
Definition: vector.hpp:73
Vector< GLfloat, 3 > Vec3f
3D float vector
Definition: vector.hpp:79
bool IsNormal(T eps=T(0)) const
Returns true if the vector is normal.
Definition: vector.hpp:320
Forward declarations.
void Multiply(T v)
Multiplies this vector by a scalar value.
Definition: vector.hpp:286
T At(const Vector &vector, std::size_t i) const T x(void) const
Returns the value of the i-th coordinate of the vector.
Definition: vector.hpp:221
void Divide(T v)
Divides this vector by a scalar value.
Definition: vector.hpp:300
Vector< GLdouble, 4 > Vec4d
4D double-precision vector
Definition: vector.hpp:111
Vector< GLdouble, 3 > Vec3d
3D double-precision vector
Definition: vector.hpp:105
static std::size_t Size(void)
The size (the number of components) of this vector.
Definition: vector.hpp:205
T Length(void) const
Returns the lenght of this vector.
Definition: vector.hpp:314
static T DotProduct(const VectorBase &a, const VectorBase &b)
Computes the dot product of vectors a and b.
Definition: vector.hpp:334
Vector< GLint, 1 > Vec1i
1D int (degenerate) vector
Definition: vector.hpp:34
friend const T * Data(const Vector &vector)
Returns a pointer to an array containing the vectors coordinates.
Definition: vector.hpp:356
void Normalize(void)
Normalizes this vector.
Definition: vector.hpp:326
Vector< GLint, 2 > Vec2i
2D int vector
Definition: vector.hpp:47
T At(std::size_t i, T fallback) const
Access to the i-th component of this vector with a fallback.
Definition: vector.hpp:236
T At(std::size_t i, std::size_t j) const
Returns the value of the element at position i, j.
Definition: matrix.hpp:416
void Divide(const VectorBase &that)
Divides the elements of this and that vector.
Definition: vector.hpp:307
const T * Data(void) const
Pointer to the components of this vector.
Definition: vector.hpp:217
void Multiply(const VectorBase &that)
Multiplies the elements of this and that vector.
Definition: vector.hpp:293
Vector< GLdouble, 2 > Vec2d
2D double-precision vector
Definition: vector.hpp:99
Base template for Matrix.
Definition: fwd.hpp:63
void Add(const VectorBase &v)
Adds v to this vector.
Definition: vector.hpp:272
Vector< GLint, 4 > Vec4i
4D int vector
Definition: vector.hpp:59
Basic template for vector types.
Definition: fwd.hpp:43
void Subtract(const VectorBase &v)
Subtracts v from this vector.
Definition: vector.hpp:279
T At(std::size_t i) const
Access to the i-th component of this vector.
Definition: vector.hpp:226
T & operator[](std::size_t i)
Access to the i-th component of this vector.
Definition: vector.hpp:246
Vector< GLfloat, 1 > Vec1f
1D float (degenerate) vector
Definition: vector.hpp:67
Definition: vector.hpp:14

Copyright © 2010-2014 Matúš Chochlík, University of Žilina, Žilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Mon Sep 22 2014 by Doxygen (version 1.8.6).