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