MorphoGraphX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Vector.hpp
Go to the documentation of this file.
1 #ifndef __VECTOR_HPP
2 #define __VECTOR_HPP
3 
10 #include <Config.hpp>
11 
12 #include <cuda/CudaGlobal.hpp>
13 #include <StaticAssert.hpp>
14 
15 #include <cassert>
16 #include <cmath>
17 #include <cstdarg>
18 #include <iostream>
19 #include <math.h>
20 
21 #ifndef COMPILE_CUDA
22 # include <QTextStream>
23 #endif
24 
25 namespace mgx { namespace util {
37  template <size_t dim, class T = float> class Vector {
38  protected:
39  T elems[dim];
40 
41  public:
42  typedef T value_type;
43  typedef T& reference_type;
44  typedef const T& const_reference_type;
45  typedef T* pointer_type;
46  typedef const T* const_pointer_type;
47  typedef T* iterator;
48  typedef const T* const_iterator;
49 
53  CU_HOST_DEVICE
54  Vector(const Vector& vec)
55  {
56  for(size_t i = 0; i < dim; i++)
57  elems[i] = vec[i];
58  }
59 
63  template <class T1> CU_HOST_DEVICE Vector(const Vector<dim, T1>& vec)
64  {
65  for(size_t i = 0; i < dim; ++i)
66  elems[i] = vec[i];
67  }
68 
72  template <size_t d1, class T1> CU_HOST_DEVICE explicit Vector(const Vector<d1, T1>& vec)
73  {
74  if(d1 < dim) {
75  for(size_t i = 0; i < d1; ++i)
76  elems[i] = vec[i];
77  for(size_t i = d1; i < dim; ++i)
78  elems[i] = 0;
79  } else {
80  for(size_t i = 0; i < dim; ++i)
81  elems[i] = vec[i];
82  }
83  }
84 
93  template <class Vec> CU_HOST_DEVICE explicit Vector(const Vec& el)
94  {
95  for(size_t i = 0; i < dim; i++)
96  elems[i] = T(el[i]);
97  }
98 
102  CU_HOST_DEVICE
103  explicit Vector(const T& x = T())
104  {
105  for(size_t i = 0; i < dim; ++i)
106  elems[i] = x;
107  }
108 
112  CU_HOST_DEVICE
113  explicit Vector(const T& x, const T& y)
114  {
115  STATIC_ASSERT(dim == 2);
116  elems[0] = x;
117  elems[1] = y;
118  }
119 
123  CU_HOST_DEVICE
124  explicit Vector(const T& x, const T& y, const T& z)
125  {
126  STATIC_ASSERT(dim == 3);
127  elems[0] = x;
128  elems[1] = y;
129  elems[2] = z;
130  }
131 
135  CU_HOST_DEVICE
136  explicit Vector(const T& x, const T& y, const T& z, const T& t)
137  {
138  STATIC_ASSERT(dim == 4);
139  elems[0] = x;
140  elems[1] = y;
141  elems[2] = z;
142  elems[3] = t;
143  }
144 
148  CU_HOST_DEVICE
149  Vector(const T& x, const T& y, const T& z, const T& a, const T& b)
150  {
151  STATIC_ASSERT(dim == 5);
152  elems[0] = x;
153  elems[1] = y;
154  elems[2] = z;
155  elems[3] = a;
156  elems[4] = b;
157  }
158 
162  CU_HOST_DEVICE
163  Vector(const T& x, const T& y, const T& z, const T& a, const T& b, const T& c)
164  {
165  STATIC_ASSERT(dim == 6);
166  elems[0] = x;
167  elems[1] = y;
168  elems[2] = z;
169  elems[3] = a;
170  elems[4] = b;
171  elems[5] = c;
172  }
173 
177  CU_HOST_DEVICE
178  Vector(const T& x, const T& y, const T& z, const T& a, const T& b, const T& c, const T& d)
179  {
180  STATIC_ASSERT(dim == 7);
181  elems[0] = x;
182  elems[1] = y;
183  elems[2] = z;
184  elems[3] = a;
185  elems[4] = b;
186  elems[5] = c;
187  elems[6] = d;
188  }
189 
193  CU_HOST_DEVICE
194  Vector(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f, const T& g, const T& h, const T& i,
195  const T& j, const T& k, const T& l)
196  {
197  STATIC_ASSERT(dim == 12);
198  elems[0] = a;
199  elems[1] = b;
200  elems[2] = c;
201  elems[3] = d;
202  elems[4] = e;
203  elems[5] = f;
204  elems[6] = g;
205  elems[7] = h;
206  elems[8] = i;
207  elems[9] = j;
208  elems[10] = k;
209  elems[11] = l;
210  }
211 
215  CU_HOST_DEVICE
216  static size_t size() {
217  return dim;
218  }
219 
223  CU_HOST_DEVICE
224  T* data() {
225  return elems;
226  }
227 
231  CU_HOST_DEVICE
233  return elems;
234  }
238  CU_HOST_DEVICE
240  return elems;
241  }
242 
246  CU_HOST_DEVICE
248  return elems + dim;
249  }
253  CU_HOST_DEVICE
254  const_iterator end() const {
255  return elems + dim;
256  }
257 
261  CU_HOST_DEVICE
262  const T* c_data() const {
263  return elems;
264  }
265 
269  CU_HOST_DEVICE
270  Vector operator-(void) const
271  {
272  Vector ans;
273  for(size_t i = 0; i < dim; i++)
274  ans[i] = -elems[i];
275 
276  return ans;
277  }
278 
282  CU_HOST_DEVICE
283  Vector operator+(const Vector& vec) const
284  {
285  Vector ans(*this);
286  ans += vec;
287  return ans;
288  }
289 
293  CU_HOST_DEVICE
294  Vector operator-(const Vector& vec) const
295  {
296  Vector ans(*this);
297  ans -= vec;
298  return ans;
299  }
300 
304  CU_HOST_DEVICE
305  Vector mult(const Vector& vec) const
306  {
307  Vector ans;
308  for(size_t i = 0; i < dim; i++)
309  ans[i] = elems[i] * vec.elems[i];
310  return ans;
311  }
312 
316  CU_HOST_DEVICE
317  Vector operator*(const T& scalar) const
318  {
319  Vector ans(*this);
320  ans *= scalar;
321  return ans;
322  }
323 
327  CU_HOST_DEVICE
328  Vector operator/(const T& scalar) const
329  {
330  Vector ans(*this);
331  ans /= scalar;
332  return ans;
333  }
334 
338  CU_HOST_DEVICE
339  Vector operator/(const Vector& vec) const
340  {
341  Vector ans = *this;
342  ans /= vec;
343  return ans;
344  }
345 
349  CU_HOST_DEVICE
350  Vector& operator/=(const Vector& vec)
351  {
352  for(size_t i = 0; i < dim; ++i)
353  elems[i] /= vec.elems[i];
354  return *this;
355  }
356 
360  CU_HOST_DEVICE
361  friend Vector operator*(const T& scalar, const Vector& vec)
362  {
363  Vector ans;
364  for(size_t i = 0; i < dim; i++)
365  ans[i] = scalar * vec.elems[i];
366 
367  return ans;
368  }
369 
373  CU_HOST_DEVICE
374  T operator*(const Vector& vec) const
375  {
376  T ans = 0;
377  for(size_t i = 0; i < dim; i++)
378  ans += elems[i] * vec.elems[i];
379 
380  return ans;
381  }
382 
386  CU_HOST_DEVICE
387  Vector& operator=(const Vector& vec)
388  {
389  for(size_t i = 0; i < dim; i++)
390  elems[i] = vec.elems[i];
391 
392  return (*this);
393  }
394 
398  CU_HOST_DEVICE
399  Vector& operator+=(const Vector& vec)
400  {
401  for(size_t i = 0; i < dim; i++)
402  elems[i] += vec.elems[i];
403  return *this;
404  }
405 
409  CU_HOST_DEVICE
410  Vector& operator+=(const T& val)
411  {
412  for(size_t i = 0; i < dim; i++)
413  elems[i] += val;
414  return *this;
415  }
416 
420  CU_HOST_DEVICE
421  Vector& operator-=(const Vector& vec)
422  {
423  for(size_t i = 0; i < dim; i++)
424  elems[i] -= vec.elems[i];
425  return *this;
426  }
427 
431  CU_HOST_DEVICE
432  Vector& operator-=(const T& val)
433  {
434  for(size_t i = 0; i < dim; i++)
435  elems[i] -= val;
436  return *this;
437  }
438 
442  CU_HOST_DEVICE
443  Vector& operator*=(const T& scalar)
444  {
445  for(size_t i = 0; i < dim; i++)
446  elems[i] *= scalar;
447  return *this;
448  }
449 
453  template <typename T1> CU_HOST_DEVICE Vector& operator*=(const T1& scalar)
454  {
455  for(size_t i = 0; i < dim; i++)
456  elems[i] = (T)(elems[i] * scalar);
457  return *this;
458  }
459 
463  CU_HOST_DEVICE
464  Vector& operator/=(const T& scalar)
465  {
466  for(size_t i = 0; i < dim; ++i)
467  elems[i] /= scalar;
468  return *this;
469  }
470 
474  template <typename T1> CU_HOST_DEVICE Vector& operator/=(const T1& scalar)
475  {
476  for(size_t i = 0; i < dim; ++i)
477  elems[i] = (T)(elems[i] / scalar);
478  return *this;
479  }
480 
484  CU_HOST_DEVICE
485  bool operator==(const Vector& vec) const
486  {
487  for(size_t i = 0; i < dim; i++)
488  if(elems[i] != vec.elems[i])
489  return false;
490 
491  return true;
492  }
493 
497  CU_HOST_DEVICE
498  bool operator!=(const Vector& vec) const {
499  return (!((*this) == vec));
500  }
501 
505  CU_HOST_DEVICE
506  T& operator[](size_t idx) {
507  return elems[idx];
508  }
509 
513  CU_HOST_DEVICE
514  const T& operator[](size_t idx) const {
515  return elems[idx];
516  }
517 
521  CU_HOST_DEVICE
522  T norm() const
523  {
524  #ifdef _MSC_VER
525  return std::sqrt((float)normsq()); // Incorrect, but stupid compiler can't compile correct code
526  #else
527  return std::sqrt(normsq());
528  #endif
529  }
530 
534  CU_HOST_DEVICE
535  T normsq() const
536  {
537  T ans = 0;
538  for(size_t i = 0; i < dim; i++)
539  ans += elems[i] * elems[i];
540 
541  return ans;
542  }
543 
547  CU_HOST_DEVICE
549  {
550  T sz = norm();
551  return ((*this) /= sz);
552  }
553 
557  CU_HOST_DEVICE
558  Vector normalized(void) const
559  {
560  Vector ans(*this);
561  return ans.normalize();
562  }
563 
564  bool iszero(void)
565  {
566  for(size_t i = 0; i < dim; i++)
567  if(elems[i] != 0)
568  return false;
569  return true;
570  }
571 
572  Vector& zero(void)
573  {
574  for(size_t i = 0; i < dim; i++)
575  elems[i] = 0;
576  return (*this);
577  }
578 
582  CU_HOST_DEVICE
583  void set(const T& x)
584  {
585  STATIC_ASSERT(dim == 1);
586  elems[0] = x;
587  }
588 
592  CU_HOST_DEVICE
593  void set(const T& x, const T& y)
594  {
595  STATIC_ASSERT(dim == 2);
596  elems[0] = x;
597  elems[1] = y;
598  }
599 
603  CU_HOST_DEVICE
604  void set(const T& x, const T& y, const T& z)
605  {
606  STATIC_ASSERT(dim == 3);
607  elems[0] = x;
608  elems[1] = y;
609  elems[2] = z;
610  }
611 
615  CU_HOST_DEVICE
616  void set(const T& x, const T& y, const T& z, const T& t)
617  {
618  STATIC_ASSERT(dim == 4);
619  elems[0] = x;
620  elems[1] = y;
621  elems[2] = z;
622  elems[3] = t;
623  }
624 
628  CU_HOST_DEVICE
629  Vector& operator=(const T& value)
630  {
631  for(size_t i = 0; i < dim; ++i) {
632  elems[i] = value;
633  }
634  return *this;
635  }
636 
640  CU_HOST_DEVICE
641  Vector cross(const Vector& other) const
642  {
643  STATIC_ASSERT(dim == 3);
644  return (*this) ^ other;
645  }
646 
650  CU_HOST_DEVICE
651  void x(const T& v)
652  {
653  STATIC_ASSERT(dim > 0);
654  elems[0] = v;
655  }
659  CU_HOST_DEVICE
660  void y(const T& v)
661  {
662  STATIC_ASSERT(dim > 1);
663  elems[1] = v;
664  }
668  CU_HOST_DEVICE
669  void z(const T& v)
670  {
671  STATIC_ASSERT(dim > 2);
672  elems[2] = v;
673  }
677  CU_HOST_DEVICE
678  void t(const T& v)
679  {
680  STATIC_ASSERT(dim > 3);
681  elems[3] = v;
682  }
686  CU_HOST_DEVICE
687  T& x()
688  {
689  STATIC_ASSERT(dim > 0);
690  return elems[0];
691  }
695  CU_HOST_DEVICE
696  T& y()
697  {
698  STATIC_ASSERT(dim > 1);
699  return elems[1];
700  }
704  CU_HOST_DEVICE
705  T& z()
706  {
707  STATIC_ASSERT(dim > 2);
708  return elems[2];
709  }
713  CU_HOST_DEVICE
714  T& t()
715  {
716  STATIC_ASSERT(dim > 3);
717  return elems[3];
718  }
722  CU_HOST_DEVICE
723  const T& x() const
724  {
725  STATIC_ASSERT(dim > 0);
726  return elems[0];
727  }
731  CU_HOST_DEVICE
732  const T& y() const
733  {
734  STATIC_ASSERT(dim > 1);
735  return elems[1];
736  }
740  CU_HOST_DEVICE
741  const T& z() const
742  {
743  STATIC_ASSERT(dim > 2);
744  return elems[2];
745  }
749  CU_HOST_DEVICE
750  const T& t() const
751  {
752  STATIC_ASSERT(dim > 3);
753  return elems[3];
754  }
755 
759  CU_HOST_DEVICE
760  void i(const T& v)
761  {
762  STATIC_ASSERT(dim > 0);
763  elems[0] = v;
764  }
768  CU_HOST_DEVICE
769  void j(const T& v)
770  {
771  STATIC_ASSERT(dim > 1);
772  elems[1] = v;
773  }
777  CU_HOST_DEVICE
778  void k(const T& v)
779  {
780  STATIC_ASSERT(dim > 2);
781  elems[2] = v;
782  }
786  CU_HOST_DEVICE
787  void l(const T& v)
788  {
789  STATIC_ASSERT(dim > 3);
790  elems[3] = v;
791  }
795  CU_HOST_DEVICE
796  T& i()
797  {
798  STATIC_ASSERT(dim > 0);
799  return elems[0];
800  }
804  CU_HOST_DEVICE
805  T& j()
806  {
807  STATIC_ASSERT(dim > 1);
808  return elems[1];
809  }
813  CU_HOST_DEVICE
814  T& k()
815  {
816  STATIC_ASSERT(dim > 2);
817  return elems[2];
818  }
822  CU_HOST_DEVICE
823  T& l()
824  {
825  STATIC_ASSERT(dim > 3);
826  return elems[3];
827  }
831  CU_HOST_DEVICE
832  const T& i() const
833  {
834  STATIC_ASSERT(dim > 0);
835  return elems[0];
836  }
840  CU_HOST_DEVICE
841  const T& j() const
842  {
843  STATIC_ASSERT(dim > 1);
844  return elems[1];
845  }
849  CU_HOST_DEVICE
850  const T& k() const
851  {
852  STATIC_ASSERT(dim > 2);
853  return elems[2];
854  }
858  CU_HOST_DEVICE
859  const T& l() const
860  {
861  STATIC_ASSERT(dim > 3);
862  return elems[3];
863  }
864 
868  CU_HOST_DEVICE
870  {
871  STATIC_ASSERT(dim > 1);
872  return Vector<2, T>(elems[0], elems[1]);
873  }
874 
880  CU_HOST_DEVICE
881  bool operator<(const Vector& other) const
882  {
883  for(size_t i = 0; i < dim; ++i) {
884  if(elems[i] < other.elems[i])
885  return true;
886  if(elems[i] > other.elems[i])
887  return false;
888  }
889  return false;
890  }
891 
897  CU_HOST_DEVICE
898  bool operator<=(const Vector& other) const
899  {
900  for(size_t i = 0; i < dim; ++i) {
901  if(elems[i] < other.elems[i])
902  return true;
903  if(elems[i] > other.elems[i])
904  return false;
905  }
906  return true;
907  }
908 
916  CU_HOST_DEVICE
917  bool operator>(const Vector& other) const
918  {
919  for(size_t i = 0; i < dim; ++i) {
920  if(elems[i] > other.elems[i])
921  return true;
922  if(elems[i] < other.elems[i])
923  return false;
924  }
925  return false;
926  }
927 
934  CU_HOST_DEVICE
935  bool operator>=(const Vector& other) const
936  {
937  for(size_t i = 0; i < dim; ++i) {
938  if(elems[i] > other.elems[i])
939  return true;
940  if(elems[i] < other.elems[i])
941  return false;
942  }
943  return true;
944  }
945 
946  friend std::ostream& operator<<(std::ostream& out, const Vector& vec)
947  {
948  for(size_t i = 0; i < dim; i++) {
949  out << vec.elems[i];
950  if(i != (dim - 1))
951  out << " ";
952  }
953  return out;
954  }
955 
956  friend std::istream& operator>>(std::istream& in, Vector& vec)
957  {
958  in >> vec[0];
959  for(size_t i = 1; i < dim && in; i++)
960  in >> std::ws >> vec[i];
961  return in;
962  }
963 
964  #ifndef COMPILE_CUDA
965  friend QTextStream& operator<<(QTextStream& out, const Vector& vec)
966  {
967  for(size_t i = 0; i < dim; i++) {
968  out << vec.elems[i];
969  if(i != (dim - 1))
970  out << " ";
971  }
972  return out;
973  }
974 
975  friend QTextStream& operator>>(QTextStream& in, Vector& vec)
976  {
977  in >> vec[0];
978  for(size_t i = 1; i < dim && !in.atEnd(); i++)
979  in >> ws >> vec[i];
980  return in;
981  }
982  #endif
983  };
984 
990  template <class T> CU_HOST_DEVICE T operator%(const Vector<2, T>& v1, const Vector<2, T>& v2) {
991  return v1 ^ v2;
992  }
993 
999  template <class T>
1000  CU_HOST_DEVICE T
1001  operator^(const Vector<2, T>& v1, const Vector<2, T>& v2) {
1002  return ((v1[0] * v2[1]) - (v1[1] * v2[0]));
1003  }
1004 
1010  template <class T>
1011  CU_HOST_DEVICE T operator^(const Vector<1, T>&, const Vector<1, T>& ) {
1012  return 0;
1013  }
1014 
1020  template <class T>
1021  CU_HOST_DEVICE Vector<3, T> operator%(const Vector<3, T>& v1, const Vector<3, T>& v2)
1022  {
1023  return v1 ^ v2;
1024  }
1025 
1031  template <class T>
1032  CU_HOST_DEVICE Vector<3, T> operator^(const Vector<3, T>& v1, const Vector<3, T>& v2) {
1033  Vector<3, T> ans;
1034  ans[0] = v1[1] * v2[2] - v1[2] * v2[1];
1035  ans[1] = v1[2] * v2[0] - v1[0] * v2[2];
1036  ans[2] = v1[0] * v2[1] - v1[1] * v2[0];
1037  return ans;
1038  }
1039 
1045  template <class T>
1046  CU_HOST_DEVICE float angle(const Vector<2, T>& v)
1047  {
1048  return atan2(v.y(), v.x());
1049  }
1050 
1056  template <class T> CU_HOST_DEVICE float angle(const Vector<3, T>& v1, const Vector<3, T>& v2)
1057  {
1058  float x = v1 * v2;
1059  float y = norm(v1 ^ v2);
1060  return atan2(y, x);
1061  }
1062 
1068  template <class T> CU_HOST_DEVICE float angle(const Vector<2, T>& v1, const Vector<2, T>& v2)
1069  {
1070  float x = v1 * v2;
1071  float y = v1 ^ v2;
1072  return atan2(y, x);
1073  }
1074 
1080  template <class T> CU_HOST_DEVICE float angle(const Vector<1, T>& v1, const Vector<1, T>& v2)
1081  {
1082  return (v1 * v2 < 0) ? -1 : 1;
1083  }
1084 
1090  template <class T> CU_HOST_DEVICE float angle(const Vector<3, T>& v1, const Vector<3, T>& v2, const Vector<3, T>& ref)
1091  {
1092  float x = v1 * v2;
1093  Vector<3, T> n = v1 ^ v2;
1094  float y = norm(n);
1095  if(n * ref < 0)
1096  return atan2(-y, x);
1097  else
1098  return atan2(y, x);
1099  }
1100 
1108  CU_HOST_DEVICE
1109  float normalized(float) {
1110  return 1;
1111  }
1112 
1120  CU_HOST_DEVICE
1121  float normsq(float s) {
1122  return s * s;
1123  }
1124 
1132  CU_HOST_DEVICE
1133  float norm(float s) {
1134  return (s < 0) ? -s : s;
1135  }
1136 
1143  template <size_t dim, typename T> CU_HOST_DEVICE T norm(const Vector<dim, T>& v) {
1144  return v.norm();
1145  }
1146 
1153  template <size_t dim, typename T> CU_HOST_DEVICE T normsq(const Vector<dim, T>& v) {
1154  return v.normsq();
1155  }
1156 
1163  template <size_t dim, typename T> CU_HOST_DEVICE Vector<dim, T> normalized(const Vector<dim, T>& v)
1164  {
1165  return v.normalized();
1166  }
1167 
1168  using ::fabs;
1169 
1175  template <size_t dim, typename T> CU_HOST_DEVICE Vector<dim, T> fabs(const Vector<dim, T>& v)
1176  {
1177  Vector<dim, T> result;
1178  for(size_t i = 0; i < dim; ++i) {
1179  result[i] = fabs(v[i]);
1180  }
1181  return result;
1182  }
1183 
1190  template <size_t dim, typename T> CU_HOST_DEVICE Vector<dim, T> max(const Vector<dim, T>& v1, const Vector<dim, T>& v2)
1191  {
1192  Vector<dim, T> result;
1193  for(size_t i = 0; i < dim; ++i) {
1194  result[i] = (v1[i] >= v2[i] ? v1[i] : v2[i]);
1195  }
1196  return result;
1197  }
1198 
1205  template <size_t dim, typename T> CU_HOST_DEVICE Vector<dim, T> min(const Vector<dim, T>& v1, const Vector<dim, T>& v2)
1206  {
1207  Vector<dim, T> result;
1208  for(size_t i = 0; i < dim; ++i) {
1209  result[i] = (v1[i] <= v2[i] ? v1[i] : v2[i]);
1210  }
1211  return result;
1212  }
1213 
1219  template <size_t dim, typename T>
1220  CU_HOST_DEVICE Vector<dim, T> trim(const Vector<dim, T>& v, const Vector<dim, T>& minv, const Vector<dim, T>& maxv)
1221  {
1222  Vector<dim, T> result;
1223  result = max(minv, min(maxv, v));
1224  return result;
1225  }
1226 
1233  template <size_t dim, typename T>
1234  CU_HOST_DEVICE Vector<dim, T> multiply(const Vector<dim, T>& v1, const Vector<dim, T>& v2)
1235  {
1236  Vector<dim, T> result;
1237  for(size_t i = 0; i < dim; ++i) {
1238  result[i] = v1[i] * v2[i];
1239  }
1240  return result;
1241  }
1242 
1243  // /**
1244  // * Return the vector whose components are clipped to min/max
1245  // * components.
1246  // *
1247  // * \relates Vector
1248  // */
1249  // template <size_t dim, typename T>
1250  // CU_HOST_DEVICE
1251  // Vector<dim,T> multiply( const Vector<dim,T>& v, const Vector<dim,T>& minv, const Vector<dim,T>& maxv)
1252  // {
1253  // Vector<dim,T> result;
1254  // result = min(minv, max(maxv, v));
1255  // return result;
1256  // }
1257 
1264  template <size_t dim, typename T>
1265  CU_HOST_DEVICE Vector<dim, T> divide(const Vector<dim, T>& v1, const Vector<dim, T>& v2)
1266  {
1267  Vector<dim, T> result;
1268  for(size_t i = 0; i < dim; ++i) {
1269  result[i] = v1[i] / v2[i];
1270  }
1271  return result;
1272  }
1273 
1279  template <typename T> CU_HOST_DEVICE Vector<3, T> orthogonal(const Vector<3, T>& v)
1280  {
1281  const float ratio = 1 - 1e-8;
1282  if((std::abs(v.y()) >= ratio * std::abs(v.x())) && (std::abs(v.z()) >= ratio * std::abs(v.x())))
1283  return Vector<3, T>(0, -v.z(), v.y());
1284  else if((std::abs(v.x()) >= ratio * std::abs(v.y())) && (std::abs(v.z()) >= ratio * std::abs(v.y())))
1285  return Vector<3, T>(-v.z(), 0, v.x());
1286  else
1287  return Vector<3, T>(-v.y(), v.x(), 0);
1288  }
1289 
1290  /*
1291  * Transform all components of a vector with a function
1292  *
1293  * \relates Vector
1294  */
1295  template <size_t dim, typename T, typename T1>
1296  CU_HOST_DEVICE Vector<dim, T> map(const T& (*fct)(const T1 &), const Vector<dim, T1>& v)
1297  {
1298  Vector<dim, T> result;
1299  for(size_t i = 0; i < dim; ++i) {
1300  result[i] = (*fct)(v[i]);
1301  }
1302  return result;
1303  }
1304 
1305  /*
1306  * Transform all components of a vector with a function
1307  *
1308  * \relates Vector
1309  */
1310  template <size_t dim, typename T, typename T1>
1311  CU_HOST_DEVICE Vector<dim, T> map(T (*fct)(const T1&), const Vector<dim, T1>& v)
1312  {
1313  Vector<dim, T> result;
1314  for(size_t i = 0; i < dim; ++i) {
1315  result[i] = (*fct)(v[i]);
1316  }
1317  return result;
1318  }
1319 
1325  template <size_t dim, typename T, typename T1> CU_HOST_DEVICE Vector<dim, T> map(T (*fct)(T1), const Vector<dim, T1>& v)
1326  {
1327  Vector<dim, T> result;
1328  for(size_t i = 0; i < dim; ++i) {
1329  result[i] = (*fct)(v[i]);
1330  }
1331  return result;
1332  }
1333 
1339  template <size_t dim, typename T>
1340  CU_HOST_DEVICE Vector<dim, T> map(const T& (*fct)(const T &, const T &), const Vector<dim, T>& v1,
1341  const Vector<dim, T>& v2)
1342  {
1343  Vector<dim, T> result;
1344  for(size_t i = 0; i < dim; ++i) {
1345  result[i] = (*fct)(v1[i], v2[i]);
1346  }
1347  return result;
1348  }
1349 
1355  template <size_t dim, typename T>
1356  CU_HOST_DEVICE Vector<dim, T> map(T (*fct)(const T&, const T&), const Vector<dim, T>& v1, const Vector<dim, T>& v2)
1357  {
1358  Vector<dim, T> result;
1359  for(size_t i = 0; i < dim; ++i) {
1360  result[i] = (*fct)(v1[i], v2[i]);
1361  }
1362  return result;
1363  }
1364 
1370  template <size_t dim, typename T>
1371  CU_HOST_DEVICE Vector<dim, T> map(T (*fct)(T, T), const Vector<dim, T>& v1, const Vector<dim, T>& v2)
1372  {
1373  Vector<dim, T> result;
1374  for(size_t i = 0; i < dim; ++i) {
1375  result[i] = (*fct)(v1[i], v2[i]);
1376  }
1377  return result;
1378  }
1379 
1385  template <size_t dim, typename T, typename T1, typename T2>
1386  CU_HOST_DEVICE Vector<dim, T> map(const T& (*fct)(const T1 &, const T2 &), const Vector<dim, T1>& v1,
1387  const Vector<dim, T2>& v2)
1388  {
1389  Vector<dim, T> result;
1390  for(size_t i = 0; i < dim; ++i) {
1391  result[i] = (*fct)(v1[i], v2[i]);
1392  }
1393  return result;
1394  }
1395 
1401  template <size_t dim, typename T, typename T1, typename T2>
1402  CU_HOST_DEVICE Vector<dim, T> map(T (*fct)(const T1&, const T2&), const Vector<dim, T1>& v1, const Vector<dim, T2>& v2)
1403  {
1404  Vector<dim, T> result;
1405  for(size_t i = 0; i < dim; ++i) {
1406  result[i] = (*fct)(v1[i], v2[i]);
1407  }
1408  return result;
1409  }
1410 
1416  template <size_t dim, typename T, typename T1, typename T2>
1417  CU_HOST_DEVICE Vector<dim, T> map(T (*fct)(T1, T2), const Vector<dim, T1>& v1, const Vector<dim, T2>& v2)
1418  {
1419  Vector<dim, T> result;
1420  for(size_t i = 0; i < dim; ++i) {
1421  result[i] = (*fct)(v1[i], v2[i]);
1422  }
1423  return result;
1424  }
1425 
1431  template <size_t dim, typename T> CU_HOST_DEVICE Vector<dim, T> operator+(const Vector<dim, T>& v, const T& value)
1432  {
1433  Vector<dim, T> res;
1434  for(size_t i = 0; i < dim; ++i)
1435  res[i] = v[i] + value;
1436  return res;
1437  }
1438 
1444  template <size_t dim, typename T> CU_HOST_DEVICE Vector<dim, T> operator+(const T& value, const Vector<dim, T>& v)
1445  {
1446  Vector<dim, T> res;
1447  for(size_t i = 0; i < dim; ++i)
1448  res[i] = v[i] + value;
1449  return res;
1450  }
1451 
1457  template <size_t dim, typename T> CU_HOST_DEVICE Vector<dim, T> operator-(const Vector<dim, T>& v, const T& value)
1458  {
1459  Vector<dim, T> res;
1460  for(size_t i = 0; i < dim; ++i)
1461  res[i] = v[i] - value;
1462  return res;
1463  }
1464 
1471  template <size_t dim, typename T> CU_HOST_DEVICE Vector<dim, T> operator-(const T& value, const Vector<dim, T>& v)
1472  {
1473  Vector<dim, T> res;
1474  for(size_t i = 0; i < dim; ++i)
1475  res[i] = value - v[i];
1476  return res;
1477  }
1478 
1486  template <size_t dim, typename T> CU_HOST_DEVICE Vector<dim + 1, T> homogeneous(const Vector<dim, T>& v)
1487  {
1488  Vector<dim + 1, T> res(v);
1489  res[dim] = T(1);
1490  return res;
1491  }
1492 
1500  template <size_t dim, typename T> CU_HOST_DEVICE Vector<dim - 1, T> cartesian(const Vector<dim, T>& v)
1501  {
1502  Vector<dim - 1, T> res(v);
1503  res /= v[dim - 1];
1504  return res;
1505  }
1506 }}
1507 
1508 #ifndef COMPILE_CUDA
1509 // Add hashes for STL
1510  #include <UnorderedMap.hpp>
1511 
1512 namespace std {
1513 
1514  #ifdef HASH_NEED_TR1
1515  namespace tr1 {
1516  #endif
1517 
1518  template <size_t dim, typename T> struct hash<mgx::util::Vector<dim, T> > {
1519  size_t operator()(const mgx::util::Vector<dim, T>& v) const
1520  {
1521  static const hash<T> hash_value = hash<T>();
1522  size_t acc = hash_value(v[0]);
1523  for(size_t i = 1; i < dim; ++i)
1524  acc ^= hash_value(v[i]);
1525  return acc;
1526  }
1527  };
1528 
1529  # ifdef HASH_NEED_TR1
1530  }
1531  # endif
1532 }
1533 
1534 #endif
1535 
1536 #endif // VECTOR_H
CU_HOST_DEVICE Vector< dim, T > operator+(const Vector< dim, T > &v, const T &value)
Add a value to all elements of a vector.
Definition: Vector.hpp:1431
CU_HOST_DEVICE Vector(const T &x, const T &y, const T &z)
Initialize a 3D vector.
Definition: Vector.hpp:124
CU_HOST_DEVICE void t(const T &v)
Short access to the fourth element.
Definition: Vector.hpp:678
CU_HOST_DEVICE T operator^(const Vector< 2, T > &v1, const Vector< 2, T > &v2)
Cross product v1 x v2 (French notation)
Definition: Vector.hpp:1001
CU_HOST_DEVICE Vector< dim, T > map(T(*fct)(const T &, const T &), const Vector< dim, T > &v1, const Vector< dim, T > &v2)
Map a function to all elements of a vector.
Definition: Vector.hpp:1356
CU_HOST_DEVICE bool operator<=(const Vector &other) const
Comparison operator.
Definition: Vector.hpp:898
CU_HOST_DEVICE Vector & operator/=(const T1 &scalar)
In-place division by a scalar.
Definition: Vector.hpp:474
CU_HOST_DEVICE Vector(const T &a, const T &b, const T &c, const T &d, const T &e, const T &f, const T &g, const T &h, const T &i, const T &j, const T &k, const T &l)
Initialize a 12D vector.
Definition: Vector.hpp:194
CU_HOST_DEVICE Vector & operator/=(const T &scalar)
In-place division by a scalar.
Definition: Vector.hpp:464
CU_HOST_DEVICE Vector< 2, T > projectXY(void)
Extract the two first elements of the vector.
Definition: Vector.hpp:869
CU_HOST_DEVICE T & j()
Short access to the second element.
Definition: Vector.hpp:805
CU_HOST_DEVICE Vector cross(const Vector &other) const
Compute the cross product as this x other.
Definition: Vector.hpp:641
CU_HOST_DEVICE const T * c_data() const
Returns a constant raw pointer on the data.
Definition: Vector.hpp:262
CU_HOST_DEVICE float angle(const Vector< 3, T > &v1, const Vector< 3, T > &v2, const Vector< 3, T > &ref)
Oriented angle between v1 and v2 with ref to orient the space.
Definition: Vector.hpp:1090
CU_HOST_DEVICE Vector< dim, T > divide(const Vector< dim, T > &v1, const Vector< dim, T > &v2)
Return the vector whose components are clipped to min/max components.
Definition: Vector.hpp:1265
CU_HOST_DEVICE Vector normalized(void) const
Returns a normalized version of the vector.
Definition: Vector.hpp:558
CU_HOST_DEVICE T & y()
Short access to the second element.
Definition: Vector.hpp:696
CU_HOST_DEVICE const T & operator[](size_t idx) const
Access to the element idx.
Definition: Vector.hpp:514
CU_HOST_DEVICE const T & l() const
Short access to the fourth element.
Definition: Vector.hpp:859
CU_HOST_DEVICE const T & j() const
Short access to the second element.
Definition: Vector.hpp:841
CU_HOST_DEVICE T & t()
Short access to the fourth element.
Definition: Vector.hpp:714
CU_HOST_DEVICE T norm() const
Euclidean norm of the vector.
Definition: Vector.hpp:522
CU_HOST_DEVICE float angle(const Vector< 2, T > &v1, const Vector< 2, T > &v2)
Oriented angle between v1 and v2.
Definition: Vector.hpp:1068
CU_HOST_DEVICE void x(const T &v)
Short access to the first element.
Definition: Vector.hpp:651
CU_HOST_DEVICE Vector(const T &x, const T &y, const T &z, const T &a, const T &b, const T &c)
Initialize a 6D vector.
Definition: Vector.hpp:163
CU_HOST_DEVICE Vector & normalize(void)
Normalize the vector.
Definition: Vector.hpp:548
CU_HOST_DEVICE Vector(const Vector< d1, T1 > &vec)
Copy another vector with different number of elements.
Definition: Vector.hpp:72
CU_HOST_DEVICE Vector operator-(void) const
Vector negation.
Definition: Vector.hpp:270
CU_HOST_DEVICE T & i()
Short access to the first element.
Definition: Vector.hpp:796
CU_HOST_DEVICE Vector< dim, T > fabs(const Vector< dim, T > &v)
Return the vector whose component is the absolute value of the input vector.
Definition: Vector.hpp:1175
CU_HOST_DEVICE float normalized(float)
Euclidean square norm of a real.
Definition: Vector.hpp:1109
CU_HOST_DEVICE Vector operator*(const T &scalar) const
Multiplication by a scalar.
Definition: Vector.hpp:317
CU_HOST_DEVICE Vector & operator*=(const T &scalar)
In-place multiplication by a scalar.
Definition: Vector.hpp:443
CU_HOST_DEVICE void set(const T &x, const T &y, const T &z, const T &t)
Set the values of a 4-D vector.
Definition: Vector.hpp:616
CU_HOST_DEVICE Vector< dim-1, T > cartesian(const Vector< dim, T > &v)
Extract the cartesion coordinates from a homogeneous vector.
Definition: Vector.hpp:1500
CU_HOST_DEVICE T norm(const Vector< dim, T > &v)
Function-version of the norm.
Definition: Vector.hpp:1143
CU_HOST_DEVICE Vector(const T &x, const T &y)
Initialize a 2D vector.
Definition: Vector.hpp:113
CU_HOST_DEVICE T operator%(const Vector< 2, T > &v1, const Vector< 2, T > &v2)
Cross product v1 x v2.
Definition: Vector.hpp:990
CU_HOST_DEVICE Vector(const T &x, const T &y, const T &z, const T &a, const T &b)
Initialize a 5D vector.
Definition: Vector.hpp:149
CU_HOST_DEVICE Vector< dim, T > multiply(const Vector< dim, T > &v1, const Vector< dim, T > &v2)
Return the vector whose component is the product of the two input vectors components.
Definition: Vector.hpp:1234
CU_HOST_DEVICE Vector(const Vector &vec)
Copy another vector.
Definition: Vector.hpp:54
CU_HOST_DEVICE const T & x() const
Short access to the first element.
Definition: Vector.hpp:723
CU_HOST_DEVICE Vector operator-(const Vector &vec) const
Vector subtraction.
Definition: Vector.hpp:294
CU_HOST_DEVICE T & x()
Short access to the first element.
Definition: Vector.hpp:687
CU_HOST_DEVICE bool operator==(const Vector &vec) const
Element-wise equality.
Definition: Vector.hpp:485
CU_HOST_DEVICE Vector & operator+=(const Vector &vec)
In-place vector addition.
Definition: Vector.hpp:399
CU_HOST_DEVICE T & operator[](size_t idx)
Access to the element idx.
Definition: Vector.hpp:506
CU_HOST_DEVICE Vector & operator-=(const T &val)
In-place value subtraction.
Definition: Vector.hpp:432
CU_HOST_DEVICE Vector< dim, T > map(T(*fct)(T1), const Vector< dim, T1 > &v)
Map a function to all elements of a vector.
Definition: Vector.hpp:1325
CU_HOST_DEVICE Vector(const Vec &el)
Initialize a vector from any object behaving like an array.
Definition: Vector.hpp:93
CU_HOST_DEVICE iterator end()
STL-iteration end.
Definition: Vector.hpp:247
CU_HOST_DEVICE Vector< 3, T > operator%(const Vector< 3, T > &v1, const Vector< 3, T > &v2)
Cross product v1 x v2.
Definition: Vector.hpp:1021
CU_HOST_DEVICE Vector & operator+=(const T &val)
In-place constant addition.
Definition: Vector.hpp:410
CU_HOST_DEVICE const_iterator end() const
Stl-iteration constant end.
Definition: Vector.hpp:254
CU_HOST_DEVICE iterator begin()
STL-iteration begin.
Definition: Vector.hpp:232
CU_HOST_DEVICE Vector mult(const Vector &vec) const
Element-wise multiplcation.
Definition: Vector.hpp:305
CU_HOST_DEVICE bool operator>=(const Vector &other) const
Comparison operator.
Definition: Vector.hpp:935
CU_HOST_DEVICE Vector & operator*=(const T1 &scalar)
In-place multiplication by a scalar.
Definition: Vector.hpp:453
CU_HOST_DEVICE T * data()
Returns a raw pointer on the data.
Definition: Vector.hpp:224
CU_HOST_DEVICE float angle(const Vector< 1, T > &v1, const Vector< 1, T > &v2)
Oriented angle between v1 and v2.
Definition: Vector.hpp:1080
CU_HOST_DEVICE void y(const T &v)
Short access to the second element.
Definition: Vector.hpp:660
CU_HOST_DEVICE Vector & operator/=(const Vector &vec)
In-place element-wise division by a scalar.
Definition: Vector.hpp:350
CU_HOST_DEVICE float normsq(float s)
Euclidean square norm of a real.
Definition: Vector.hpp:1121
CU_HOST_DEVICE Vector< dim, T > min(const Vector< dim, T > &v1, const Vector< dim, T > &v2)
Return the vector whose component is the min of the two input vectors components. ...
Definition: Vector.hpp:1205
CU_HOST_DEVICE Vector< dim, T > normalized(const Vector< dim, T > &v)
Function-version of the square norm.
Definition: Vector.hpp:1163
CU_HOST_DEVICE Vector(const T &x, const T &y, const T &z, const T &a, const T &b, const T &c, const T &d)
Initialize a 7D vector.
Definition: Vector.hpp:178
Namespace containing all the utility classes.
Definition: Vector.hpp:37
CU_HOST_DEVICE void i(const T &v)
Short access to the first element.
Definition: Vector.hpp:760
CU_HOST_DEVICE Vector operator/(const T &scalar) const
Division by a scalar.
Definition: Vector.hpp:328
CU_HOST_DEVICE Vector(const T &x, const T &y, const T &z, const T &t)
Initialize a 4D vector.
Definition: Vector.hpp:136
CU_HOST_DEVICE Vector< dim, T > map(T(*fct)(T1, T2), const Vector< dim, T1 > &v1, const Vector< dim, T2 > &v2)
Map a function to all elements of a vector.
Definition: Vector.hpp:1417
#define STATIC_ASSERT(B)
Assertion that works at compile time.
Definition: StaticAssert.hpp:47
CU_HOST_DEVICE bool operator<(const Vector &other) const
Comparison operator.
Definition: Vector.hpp:881
CU_HOST_DEVICE void set(const T &x, const T &y, const T &z)
Set the values of a 3-D vector.
Definition: Vector.hpp:604
CU_HOST_DEVICE void set(const T &x, const T &y)
Set the values of a 2-D vector.
Definition: Vector.hpp:593
CU_HOST_DEVICE Vector & operator-=(const Vector &vec)
In-place vector subtraction.
Definition: Vector.hpp:421
CU_HOST_DEVICE T normsq(const Vector< dim, T > &v)
Function-version of the square norm.
Definition: Vector.hpp:1153
static CU_HOST_DEVICE size_t size()
Returns the size of the vector (i.e.
Definition: Vector.hpp:216
CU_HOST_DEVICE const T & z() const
Short access to the third element.
Definition: Vector.hpp:741
CU_HOST_DEVICE Vector operator/(const Vector &vec) const
Element-wise division.
Definition: Vector.hpp:339
CU_HOST_DEVICE T normsq() const
Square of the Euclidean norm of the vector.
Definition: Vector.hpp:535
CU_HOST_DEVICE Vector< dim, T > trim(const Vector< dim, T > &v, const Vector< dim, T > &minv, const Vector< dim, T > &maxv)
Return the vector with components clipped to min and max vectors.
Definition: Vector.hpp:1220
Define the STATIC_ASSERT macro.
CU_HOST_DEVICE T & z()
Short access to the third element.
Definition: Vector.hpp:705
CU_HOST_DEVICE float norm(float s)
Euclidean norm of a real.
Definition: Vector.hpp:1133
CU_HOST_DEVICE T & l()
Short access to the fourth element.
Definition: Vector.hpp:823
CU_HOST_DEVICE friend Vector operator*(const T &scalar, const Vector &vec)
Multiplication by a scalar.
Definition: Vector.hpp:361
CU_HOST_DEVICE void set(const T &x)
Set the values of a 1-D vector.
Definition: Vector.hpp:583
CU_HOST_DEVICE void l(const T &v)
Short access to the fourth element.
Definition: Vector.hpp:787
CU_HOST_DEVICE const T & t() const
Short access to the fourth element.
Definition: Vector.hpp:750
CU_HOST_DEVICE void z(const T &v)
Short access to the third element.
Definition: Vector.hpp:669
CU_HOST_DEVICE Vector< dim, T > map(T(*fct)(const T1 &, const T2 &), const Vector< dim, T1 > &v1, const Vector< dim, T2 > &v2)
Map a function to all elements of a vector.
Definition: Vector.hpp:1402
CU_HOST_DEVICE Vector< dim, T > operator-(const Vector< dim, T > &v, const T &value)
Substact a value to all elements of a vector.
Definition: Vector.hpp:1457
CU_HOST_DEVICE void k(const T &v)
Short access to the third element.
Definition: Vector.hpp:778
CU_HOST_DEVICE Vector< 3, T > operator^(const Vector< 3, T > &v1, const Vector< 3, T > &v2)
Cross product v1 x v2 (French notation)
Definition: Vector.hpp:1032
CU_HOST_DEVICE bool operator>(const Vector &other) const
Comparison operator.
Definition: Vector.hpp:917
CU_HOST_DEVICE Vector< dim, T > map(const T &(*fct)(const T1 &, const T2 &), const Vector< dim, T1 > &v1, const Vector< dim, T2 > &v2)
Map a function to all elements of a vector.
Definition: Vector.hpp:1386
CU_HOST_DEVICE Vector operator+(const Vector &vec) const
Vector addition.
Definition: Vector.hpp:283
CU_HOST_DEVICE T operator*(const Vector &vec) const
Dot product.
Definition: Vector.hpp:374
CU_HOST_DEVICE Vector< dim+1, T > homogeneous(const Vector< dim, T > &v)
Create a homogeneous coordinate vector from a cartesian one.
Definition: Vector.hpp:1486
CU_HOST_DEVICE Vector< dim, T > max(const Vector< dim, T > &v1, const Vector< dim, T > &v2)
Return the vector whose component is the max of the two input vectors components. ...
Definition: Vector.hpp:1190
CU_HOST_DEVICE float angle(const Vector< 2, T > &v)
Angle of the vector with (0,1)
Definition: Vector.hpp:1046
CU_HOST_DEVICE Vector & operator=(const T &value)
Set all the elements to value.
Definition: Vector.hpp:629
CU_HOST_DEVICE T operator^(const Vector< 1, T > &, const Vector< 1, T > &)
Cross product v1 x v2 (French notation)
Definition: Vector.hpp:1011
CU_HOST_DEVICE float angle(const Vector< 3, T > &v1, const Vector< 3, T > &v2)
Non-oriented angle between v1 and v2.
Definition: Vector.hpp:1056
CU_HOST_DEVICE Vector< dim, T > operator-(const T &value, const Vector< dim, T > &v)
Equivalent to substracting a vector with all component the same to another one.
Definition: Vector.hpp:1471
CU_HOST_DEVICE Vector< dim, T > map(T(*fct)(T, T), const Vector< dim, T > &v1, const Vector< dim, T > &v2)
Map a function to all elements of a vector.
Definition: Vector.hpp:1371
CU_HOST_DEVICE T & k()
Short access to the third element.
Definition: Vector.hpp:814
CU_HOST_DEVICE Vector(const Vector< dim, T1 > &vec)
Copy another vector with different number of elements.
Definition: Vector.hpp:63
CU_HOST_DEVICE const T & y() const
Short access to the second element.
Definition: Vector.hpp:732
CU_HOST_DEVICE const_iterator begin() const
Stl-iteration constant begin.
Definition: Vector.hpp:239
CU_HOST_DEVICE const T & k() const
Short access to the third element.
Definition: Vector.hpp:850
CU_HOST_DEVICE Vector< 3, T > orthogonal(const Vector< 3, T > &v)
Find a vector orthogonal to v.
Definition: Vector.hpp:1279
CU_HOST_DEVICE bool operator!=(const Vector &vec) const
Element-wise inequality.
Definition: Vector.hpp:498
CU_HOST_DEVICE void j(const T &v)
Short access to the second element.
Definition: Vector.hpp:769
CU_HOST_DEVICE Vector< dim, T > map(const T &(*fct)(const T &, const T &), const Vector< dim, T > &v1, const Vector< dim, T > &v2)
Map a function to all elements of a vector.
Definition: Vector.hpp:1340
CU_HOST_DEVICE Vector & operator=(const Vector &vec)
Vector copy.
Definition: Vector.hpp:387
CU_HOST_DEVICE Vector(const T &x=T())
Initialize a vector with all values to x.
Definition: Vector.hpp:103
CU_HOST_DEVICE const T & i() const
Short access to the first element.
Definition: Vector.hpp:832
CU_HOST_DEVICE Vector< dim, T > operator+(const T &value, const Vector< dim, T > &v)
Add a value to all elements of a vector.
Definition: Vector.hpp:1444