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