Tulip  4.4.0
Better Visualization Through Research
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Groups Pages
Vector.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux 1 and Inria Bordeaux - Sud Ouest
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 ///@cond DOXYGEN_HIDDEN
20 
21 //@TLPGEOLICENCE#
22 
23 #ifndef _TLP_VECTOR_H
24 #define _TLP_VECTOR_H
25 
26 #include <cassert>
27 #include <tulip/Array.h>
28 #include <tulip/tuliphash.h>
29 #include <cmath>
30 #include <limits>
31 #include <cstring>
32 
33 #define VECTOR Vector<TYPE,SIZE,OTYPE,DTYPE>
34 #define TEMPLATEVECTOR template <typename TYPE, unsigned int SIZE, typename OTYPE, typename DTYPE>
35 
36 namespace tlp {
37 
38 template<typename TYPE, typename OTYPE>
39 inline OTYPE tlpsqr(const TYPE a) {
40  return static_cast<OTYPE>(a) * static_cast<OTYPE>(a);
41 }
42 
43 template<typename TYPE, typename OTYPE>
44 inline TYPE tlpsqrt(const OTYPE a) {
45  return static_cast<TYPE>(sqrt(a));
46 }
47 
48 template<>
49 inline double tlpsqrt<double, long double>(long double a) {
50  return static_cast<double>(sqrtl(a));
51 }
52 
53 
54 /**
55  * @ingroup Structures
56  * \brief class for mathematical vector
57  *
58  * Enables to create a Vector of TYPE (must be a numeric basic type) with a
59  * fixed size and provides Mathematical operation. Mathematical
60  * operators must be defined for TYPE. Out of bound accesses are only checked
61  * in debug mode. The OTYPE is used for temporary computation to prevent overflow,
62  * by default OTYPE is a double.
63  *
64  * \author : David Auber auber@tulip-software.org
65  * \version 0.0.1 24/01/2003
66  */
67 template <typename TYPE, unsigned int SIZE, typename OTYPE = double, typename DTYPE = TYPE>
68 class Vector:public Array<TYPE,SIZE> {
69 public:
70  inline VECTOR() {
71  memset( &((*this)[0]), 0, SIZE * sizeof(TYPE) );
72  }
73  inline VECTOR(const Vector<TYPE, SIZE, OTYPE> &v) {
74  set(v);
75  }
76 
77  inline VECTOR(const Vector<TYPE, SIZE + 1, OTYPE> &v) {
78  set(v);
79  }
80 
81  explicit inline VECTOR(const TYPE x) {
82  fill(x);
83  /*
84  if (int(SIZE) - 1 > 0)
85  memset( &((*this)[1]), 0, (SIZE - 1) * sizeof(TYPE) );
86  set(x);
87  */
88  }
89 
90  explicit inline VECTOR(const TYPE x, const TYPE y) {
91  if (int(SIZE) - 2 > 0)
92  memset( &((*this)[2]), 0, (SIZE - 2) * sizeof(TYPE) );
93 
94  set(x,y);
95  }
96 
97  explicit inline VECTOR(const TYPE x, const TYPE y, const TYPE z) {
98  if (int(SIZE) - 3 > 0)
99  memset( &((*this)[3]), 0, (SIZE - 3) * sizeof(TYPE) );
100 
101  set(x, y, z);
102  }
103  explicit inline VECTOR(const Vector<TYPE, 2, OTYPE> &v, const TYPE z) {
104  set(v, z);
105  }
106  explicit inline VECTOR(const TYPE x, const TYPE y, const TYPE z, const TYPE w) {
107  set(x, y, z, w);
108  }
109  explicit inline VECTOR(const Vector<TYPE, 2, OTYPE> &v, const TYPE z, const TYPE w) {
110  set(v, z, w);
111  }
112  explicit inline VECTOR(const Vector<TYPE, 3, OTYPE> &v, const TYPE w) {
113  set(v, w);
114  }
115 
116  inline void set(const TYPE x) {
117  (*this)[0] = x;
118  }
119  inline void set(const TYPE x, const TYPE y) {
120  assert(SIZE>1);
121  (*this)[0] = x;
122  (*this)[1] = y;
123  }
124  inline void set(const TYPE x, const TYPE y, const TYPE z) {
125  assert(SIZE>2);
126  (*this)[0] = x;
127  (*this)[1] = y;
128  (*this)[2] = z;
129  }
130  inline void set(const TYPE x, const TYPE y, const TYPE z, const TYPE w) {
131  assert(SIZE>3);
132  (*this)[0] = x;
133  (*this)[1] = y;
134  (*this)[2] = z;
135  (*this)[3] = w;
136  }
137  inline void set(const Vector<TYPE, 2, OTYPE> &v, const TYPE z) {
138  assert(SIZE>2);
139  memcpy( &((*this)[0]), (void*)&(v.array[0]), 2 * sizeof(TYPE) );
140  (*this)[2] = z;
141  }
142  inline void set(const Vector<TYPE, 2, OTYPE> &v, const TYPE z, const TYPE w) {
143  assert(SIZE>3);
144  memcpy( &((*this)[0]), (void*)&(v.array[0]), 2 * sizeof(TYPE) );
145  (*this)[2] = z;
146  (*this)[3] = w;
147  }
148  inline void set(const Vector<TYPE, 3, OTYPE> &v, const TYPE w) {
149  assert(SIZE>3);
150  memcpy( &((*this)[0]), (void*)&(v.array[0]), 3 * sizeof(TYPE) );
151  (*this)[3] = w;
152  }
153  inline void set(const Vector<TYPE, SIZE, OTYPE> &v) {
154  memcpy(&((*this)[0]), (void*)&(v.array[0]), SIZE * sizeof(TYPE) );
155  }
156  inline void set(const Vector<TYPE, SIZE + 1, OTYPE> &v) {
157  memcpy(&((*this)[0]), &(v.array[0]), SIZE * sizeof(TYPE) );
158  }
159  inline void get(TYPE &x) const {
160  x = (*this)[0];
161  }
162  inline void get(TYPE &x,TYPE &y) const {
163  assert(SIZE>1);
164  x = (*this)[0];
165  y = (*this)[1];
166  }
167  inline void get(TYPE &x,TYPE &y,TYPE &z) const {
168  assert(SIZE>2);
169  x = (*this)[0];
170  y = (*this)[1];
171  z = (*this)[2];
172  }
173  inline void get(TYPE &x,TYPE &y,TYPE &z,TYPE &w) const {
174  assert(SIZE>3);
175  x = (*this)[0];
176  y = (*this)[1];
177  z = (*this)[2];
178  w = (*this)[3];
179  }
180 
181  //convenient accessor for coordinates
182  inline TYPE x() const {
183  return (*this)[0];
184  }
185  inline TYPE y() const {
186  assert(SIZE>1);
187  return (*this)[1];
188  }
189  inline TYPE z() const {
190  assert(SIZE>2);
191  return (*this)[2];
192  }
193  inline TYPE w() const {
194  assert(SIZE>3);
195  return (*this)[3];
196  }
197 
198  inline TYPE& x() {
199  return (*this)[0];
200  }
201  inline TYPE& y() {
202  assert(SIZE>1);
203  return (*this)[1];
204  }
205  inline TYPE& z() {
206  assert(SIZE>2);
207  return (*this)[2];
208  }
209  inline TYPE& w() {
210  assert(SIZE>3);
211  return (*this)[3];
212  }
213 
214  inline TYPE width() const {
215  return x();
216  }
217  inline TYPE height() const {
218  return y();
219  }
220  inline TYPE depth() const {
221  return z();
222  }
223 
224  inline TYPE& width() {
225  return x();
226  }
227  inline TYPE& height() {
228  return y();
229  }
230  inline TYPE& depth() {
231  return z();
232  }
233 
234  inline TYPE r() const {
235  return x();
236  }
237  inline TYPE g() const {
238  return y();
239  }
240  inline TYPE b() const {
241  return z();
242  }
243  inline TYPE a() const {
244  return w();
245  }
246 
247  inline TYPE& r() {
248  return x();
249  }
250  inline TYPE& g() {
251  return y();
252  }
253  inline TYPE& b() {
254  return z();
255  }
256  inline TYPE& a() {
257  return w();
258  }
259 
260  inline TYPE s() const {
261  return x();
262  }
263  inline TYPE t() const {
264  return y();
265  }
266  inline TYPE p() const {
267  return z();
268  }
269  inline TYPE q() const {
270  return w();
271  }
272 
273  inline TYPE& s() {
274  return x();
275  }
276  inline TYPE& t() {
277  return y();
278  }
279  inline TYPE& p() {
280  return z();
281  }
282  inline TYPE& q() {
283  return w();
284  }
285 
286  inline void setX(TYPE xx) {
287  x() = xx;
288  }
289  inline void setY(TYPE yy) {
290  y() = yy;
291  }
292  inline void setZ(TYPE zz) {
293  z() = zz;
294  }
295 
296  inline TYPE getX() const {
297  return x();
298  }
299  inline TYPE getY() const {
300  return y();
301  }
302  inline TYPE getZ() const {
303  return z();
304  }
305 
306  inline void setW(const TYPE width) {
307  x() = width;
308  }
309 
310  inline void setH(const TYPE height) {
311  y() = height;
312  }
313 
314  inline void setD(const TYPE depth) {
315  z() = depth;
316  }
317 
318  inline TYPE getW() const {
319  return x();
320  }
321  inline TYPE getH() const {
322  return y();
323  }
324  inline TYPE getD() const {
325  return z();
326  }
327 
328 
329 
330 // inline VECTOR & operator*=(const OTYPE );
331  inline VECTOR & operator*=(const TYPE );
332  inline VECTOR & operator*=(const VECTOR &);
333 // inline VECTOR & operator/=(const OTYPE );
334  inline VECTOR & operator/=(const TYPE );
335  inline VECTOR & operator/=(const VECTOR &);
336 // inline VECTOR & operator+=(const OTYPE );
337  inline VECTOR & operator+=(const TYPE );
338  inline VECTOR & operator+=(const VECTOR &);
339 // inline VECTOR & operator-=(const OTYPE );
340  inline VECTOR & operator-=(const TYPE );
341  inline VECTOR & operator-=(const VECTOR &);
342  inline VECTOR & operator^=(const VECTOR &);
343 
344  inline bool operator>(const VECTOR &) const;
345  inline bool operator<(const VECTOR &) const;
346  inline bool operator!=(const VECTOR &) const;
347  inline bool operator==(const VECTOR &) const;
348  inline VECTOR & fill(const TYPE obj);
349  inline TYPE norm () const;
350  inline TYPE length () const {
351  return norm();
352  }
353  inline VECTOR & normalize () {
354  OTYPE tmp = 0;
355 
356  for (unsigned int i=0; i<SIZE; ++i)
357  tmp += tlpsqr<TYPE, OTYPE>((*this)[i]);
358 
359  if (tmp < sqrt(std::numeric_limits<TYPE>::epsilon())) {
360  return *this;
361  }
362 
363  for (unsigned int i=0; i<SIZE; ++i) {
364  if ((*this)[i] < 0.)
365  (*this)[i] = -tlpsqrt<TYPE, OTYPE>(tlpsqr<TYPE, OTYPE>((*this)[i]) / tmp);
366  else
367  (*this)[i] = tlpsqrt<TYPE, OTYPE>(tlpsqr<TYPE, OTYPE>((*this)[i]) / tmp);
368  }
369 
370  return *this;
371  }
372  inline DTYPE dist (const VECTOR &) const;
373  inline TYPE dotProduct(const VECTOR &) const;
374 };
375 
376 TEMPLATEVECTOR
377 inline TYPE dotProduct(const VECTOR &a, const VECTOR &b) {
378  return a.dotProduct(b);
379 }
380 
381 TEMPLATEVECTOR
382 inline TYPE dist(const VECTOR &a, const VECTOR &b) {
383  return a.dist(b);
384 }
385 
386 
387 /**
388  * Return the minimun of each dimension of the two vectors
389  * for instance for a 2 vectors of dim 2 :
390  * min(V1, V2) = (min(V1[0], v2[0]), min(V1[1], v2[1))
391  */
392 TEMPLATEVECTOR
393 inline VECTOR minVector(const VECTOR &u, const VECTOR &v) {
394  VECTOR tmp;
395 
396  for(unsigned int i = 0; i<SIZE; ++i)
397  tmp[i] = std::min(u[i], v[i]);
398 
399  return tmp;
400 }
401 /**
402  * Return the maximum of each dimension of the two vectors
403  * for instance for a 2 vectors of dim 2 :
404  * max(V1, V2) = (max(V1[0], v2[0]), max(V1[1], v2[1))
405  */
406 TEMPLATEVECTOR
407 inline VECTOR maxVector(const VECTOR &u, const VECTOR &v) {
408  VECTOR tmp;
409 
410  for(unsigned int i = 0; i<SIZE; ++i)
411  tmp[i] = std::max(u[i], v[i]);
412 
413  return tmp;
414 }
415 
416 TEMPLATEVECTOR
417 inline VECTOR operator*(const VECTOR &, const VECTOR &);
418 TEMPLATEVECTOR
419 inline VECTOR operator*(const TYPE , const VECTOR &);
420 TEMPLATEVECTOR
421 inline VECTOR operator*(const VECTOR &, const TYPE );
422 
423 //TEMPLATEVECTOR
424 //inline VECTOR operator*(const OTYPE , const VECTOR &);
425 //TEMPLATEVECTOR
426 //inline VECTOR operator*(const VECTOR &, const OTYPE );
427 
428 TEMPLATEVECTOR
429 inline VECTOR operator+(const VECTOR &, const VECTOR &);
430 TEMPLATEVECTOR
431 inline VECTOR operator+(const VECTOR &, const TYPE );
432 //TEMPLATEVECTOR
433 //inline VECTOR operator+(const VECTOR &, const OTYPE );
434 
435 TEMPLATEVECTOR
436 inline VECTOR operator-(const VECTOR &, const VECTOR &);
437 TEMPLATEVECTOR
438 inline VECTOR operator-(const VECTOR &, const TYPE );
439 //TEMPLATEVECTOR
440 //inline VECTOR operator-(const VECTOR &, const OTYPE );
441 
442 TEMPLATEVECTOR
443 inline VECTOR operator/(const VECTOR &, const VECTOR &);
444 TEMPLATEVECTOR
445 inline VECTOR operator/(const VECTOR &, const TYPE );
446 //TEMPLATEVECTOR
447 //inline VECTOR operator/(const VECTOR &, const OTYPE );
448 
449 TEMPLATEVECTOR
450 inline VECTOR operator^(const VECTOR &, const VECTOR &);
451 TEMPLATEVECTOR
452 inline VECTOR operator-(const VECTOR&);
453 /**
454  * @brief typedef for 2D vector of unsigned int
455  */
456 typedef Vector<unsigned int, 2> Vec2ui;
457 /**
458  * @brief typedef for 3D vector of unsigned int
459  */
460 typedef Vector<unsigned int, 3> Vec3ui;
461 /**
462  * @brief typedef for 4D vector of unsigned int
463  */
464 typedef Vector<unsigned int, 4> Vec4ui;
465 /**
466  * @brief typedef for 2D vector of int
467  */
468 typedef Vector<int, 2> Vec2i;
469 /**
470  * @brief typedef for 3D vector of int
471  */
472 typedef Vector<int, 3> Vec3i;
473 /**
474  * @brief typedef for 4D vector of int
475  */
476 typedef Vector<int, 4> Vec4i;
477 /**
478  * @brief typedef for 2D vector of double
479  */
480 typedef Vector<double, 2, long double> Vec2d;
481 /**
482  * @brief typedef for 3D vector of double
483  */
484 typedef Vector<double, 3, long double> Vec3d;
485 /**
486  * @brief typedef for 4D vector of double
487  */
488 typedef Vector<double, 4, long double> Vec4d;
489 /**
490  * @brief typedef for 2D vector of float
491  */
492 typedef Vector<float, 2, double> Vec2f;
493 /**
494  * @brief typedef for 3D vector of float
495  */
496 typedef Vector<float, 3, double> Vec3f;
497 /**
498  * @brief typedef for 4D vector of float
499  */
500 typedef Vector<float, 4, double> Vec4f;
501 }
502 
503 #ifdef _MSC_VER
504 //template<unsigned int SIZE>
505 static double sqrt(tlp::Vector<float, 5>& v) {
506  return sqrt((double)v[0]);
507 }
508 
509 template class TLP_SCOPE tlp::Vector<unsigned char, 4>;
510 
511 #endif
512 
513 TLP_BEGIN_HASH_NAMESPACE {
514  TEMPLATEVECTOR
515  size_t hash_vector(const tlp::VECTOR &v) {
516  size_t seed = 0;
517 
518  for (unsigned int i = 0 ; i < SIZE ; ++i) {
519  hash_combine(seed, v[i]);
520  }
521 
522  return seed;
523  }
524 
525  template <>
526  struct hash<tlp::Vec2ui> {
527  inline std::size_t operator()(const tlp::Vec2ui &v) const {
528  return hash_vector(v);
529  }
530  };
531 
532  template <>
533  struct hash<tlp::Vec3ui> {
534  inline std::size_t operator()(const tlp::Vec3ui &v) const {
535  return hash_vector(v);
536  }
537  };
538 
539  template <>
540  struct hash<tlp::Vec4ui> {
541  inline std::size_t operator()(const tlp::Vec4ui &v) const {
542  return hash_vector(v);
543  }
544  };
545 
546  template <>
547  struct hash<tlp::Vec2i> {
548  inline std::size_t operator()(const tlp::Vec2i &v) const {
549  return hash_vector(v);
550  }
551  };
552 
553  template <>
554  struct hash<tlp::Vec3i> {
555  inline std::size_t operator()(const tlp::Vec3i &v) const {
556  return hash_vector(v);
557  }
558  };
559 
560  template <>
561  struct hash<tlp::Vec4i> {
562  inline std::size_t operator()(const tlp::Vec4i &v) const {
563  return hash_vector(v);
564  }
565  };
566 
567  template <>
568  struct hash<tlp::Vec2d> {
569  inline std::size_t operator()(const tlp::Vec2d &v) const {
570  return hash_vector(v);
571  }
572  };
573 
574  template <>
575  struct hash<tlp::Vec3d> {
576  inline std::size_t operator()(const tlp::Vec3f &v) const {
577  return hash_vector(v);
578  }
579  };
580 
581  template <>
582  struct hash<tlp::Vec4d> {
583  inline std::size_t operator()(const tlp::Vec4d &v) const {
584  return hash_vector(v);
585  }
586  };
587 
588  template <>
589  struct hash<tlp::Vec2f> {
590  inline std::size_t operator()(const tlp::Vec2f &v) const {
591  return hash_vector(v);
592  }
593  };
594 
595  template <>
596  struct hash<tlp::Vec3f> {
597  inline std::size_t operator()(const tlp::Vec3f &v) const {
598  return hash_vector(v);
599  }
600  };
601 
602  template <>
603  struct hash<tlp::Vec4f> {
604  inline std::size_t operator()(const tlp::Vec4f &v) const {
605  return hash_vector(v);
606  }
607  };
608 
609 
610 } TLP_END_HASH_NAMESPACE
611 
612 #include "cxx/Vector.cxx"
613 
614 // fix for bug #3598871: allow use of VECTOR keyword in other software
615 #undef VECTOR
616 #undef TEMPLATEVECTOR
617 
618 #endif
619 ///@endcond