Tulip  6.0.0
Large graphs analysis and drawing
Vector.h
1 /*
2  *
3  * This file is part of Tulip (https://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/TlpTools.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  inline VECTOR &operator=(const VECTOR &) = default;
357 };
358 
359 TEMPLATEVECTOR
360 inline TYPE dotProduct(const VECTOR &a, const VECTOR &b) {
361  return a.dotProduct(b);
362 }
363 
364 TEMPLATEVECTOR
365 inline TYPE dist(const VECTOR &a, const VECTOR &b) {
366  return a.dist(b);
367 }
368 
369 /**
370  * Return the minimum of each dimension of the two vectors
371  * for instance for a 2 vectors of dim 2 :
372  * min(V1, V2) = (min(V1[0], v2[0]), min(V1[1], v2[1))
373  */
374 TEMPLATEVECTOR
375 inline VECTOR minVector(const VECTOR &u, const VECTOR &v) {
376  VECTOR tmp;
377 
378  for (size_t i = 0; i < SIZE; ++i)
379  tmp[i] = std::min(u[i], v[i]);
380 
381  return tmp;
382 }
383 /**
384  * Return the maximum of each dimension of the two vectors
385  * for instance for a 2 vectors of dim 2 :
386  * max(V1, V2) = (max(V1[0], v2[0]), max(V1[1], v2[1))
387  */
388 TEMPLATEVECTOR
389 inline VECTOR maxVector(const VECTOR &u, const VECTOR &v) {
390  VECTOR tmp;
391 
392  for (size_t i = 0; i < SIZE; ++i)
393  tmp[i] = std::max(u[i], v[i]);
394 
395  return tmp;
396 }
397 
398 /**
399  * compute the minimum/maximum of each dimension of the two vectors
400  */
401 TEMPLATEVECTOR
402 inline void minMaxVectors(const VECTOR &u, const VECTOR &v, VECTOR &min, VECTOR &max) {
403  for (size_t i = 0; i < SIZE; ++i) {
404  if (u[i] > v[i]) {
405  max[i] = u[i];
406  min[i] = v[i];
407  } else {
408  min[i] = u[i];
409  max[i] = v[i];
410  }
411  }
412 }
413 
414 TEMPLATEVECTOR
415 inline VECTOR operator*(const VECTOR &, const VECTOR &);
416 TEMPLATEVECTOR
417 inline VECTOR operator*(const TYPE, const VECTOR &);
418 TEMPLATEVECTOR
419 inline VECTOR operator*(const VECTOR &, const TYPE);
420 
421 TEMPLATEVECTOR
422 inline VECTOR operator+(const VECTOR &, const VECTOR &);
423 TEMPLATEVECTOR
424 inline VECTOR operator+(const VECTOR &, const TYPE);
425 
426 TEMPLATEVECTOR
427 inline VECTOR operator-(const VECTOR &, const VECTOR &);
428 TEMPLATEVECTOR
429 inline VECTOR operator-(const VECTOR &, const TYPE);
430 
431 TEMPLATEVECTOR
432 inline VECTOR operator/(const VECTOR &, const VECTOR &);
433 TEMPLATEVECTOR
434 inline VECTOR operator/(const VECTOR &, const TYPE);
435 
436 TEMPLATEVECTOR
437 inline VECTOR operator^(const VECTOR &, const VECTOR &);
438 TEMPLATEVECTOR
439 inline VECTOR operator-(const VECTOR &);
440 /**
441  * @brief typedef for 2D vector of unsigned int
442  */
443 typedef Vector<unsigned int, 2> Vec2ui;
444 /**
445  * @brief typedef for 3D vector of unsigned int
446  */
447 typedef Vector<unsigned int, 3> Vec3ui;
448 /**
449  * @brief typedef for 4D vector of unsigned int
450  */
451 typedef Vector<unsigned int, 4> Vec4ui;
452 /**
453  * @brief typedef for 2D vector of int
454  */
455 typedef Vector<int, 2> Vec2i;
456 /**
457  * @brief typedef for 3D vector of int
458  */
459 typedef Vector<int, 3> Vec3i;
460 /**
461  * @brief typedef for 4D vector of int
462  */
463 typedef Vector<int, 4> Vec4i;
464 /**
465  * @brief typedef for 2D vector of double
466  */
467 typedef Vector<double, 2, long double> Vec2d;
468 /**
469  * @brief typedef for 3D vector of double
470  */
471 typedef Vector<double, 3, long double> Vec3d;
472 /**
473  * @brief typedef for 4D vector of double
474  */
475 typedef Vector<double, 4, long double> Vec4d;
476 /**
477  * @brief typedef for 2D vector of float
478  */
479 typedef Vector<float, 2, double> Vec2f;
480 /**
481  * @brief typedef for 3D vector of float
482  */
483 typedef Vector<float, 3, double> Vec3f;
484 /**
485  * @brief typedef for 4D vector of float
486  */
487 typedef Vector<float, 4, double> Vec4f;
488 } // namespace tlp
489 
490 #ifdef _MSC_VER
491 static double sqrt(tlp::Vector<float, 5> &v) {
492  return sqrt((double)v[0]);
493 }
494 
495 template class TLP_SCOPE tlp::Vector<unsigned char, 4>;
496 
497 #endif
498 
499 namespace std {
500 TEMPLATEVECTOR
501 size_t hash_vector(const tlp::VECTOR &v) {
502  size_t seed = 0;
503 
504  for (size_t i = 0; i < SIZE; ++i) {
505  tlp_hash_combine(seed, v[i]);
506  }
507 
508  return seed;
509 }
510 
511 template <>
512 struct hash<tlp::Vec2ui> {
513  inline std::size_t operator()(const tlp::Vec2ui &v) const {
514  return hash_vector(v);
515  }
516 };
517 
518 template <>
519 struct hash<tlp::Vec3ui> {
520  inline std::size_t operator()(const tlp::Vec3ui &v) const {
521  return hash_vector(v);
522  }
523 };
524 
525 template <>
526 struct hash<tlp::Vec4ui> {
527  inline std::size_t operator()(const tlp::Vec4ui &v) const {
528  return hash_vector(v);
529  }
530 };
531 
532 template <>
533 struct hash<tlp::Vec2i> {
534  inline std::size_t operator()(const tlp::Vec2i &v) const {
535  return hash_vector(v);
536  }
537 };
538 
539 template <>
540 struct hash<tlp::Vec3i> {
541  inline std::size_t operator()(const tlp::Vec3i &v) const {
542  return hash_vector(v);
543  }
544 };
545 
546 template <>
547 struct hash<tlp::Vec4i> {
548  inline std::size_t operator()(const tlp::Vec4i &v) const {
549  return hash_vector(v);
550  }
551 };
552 
553 template <>
554 struct hash<tlp::Vec2d> {
555  inline std::size_t operator()(const tlp::Vec2d &v) const {
556  return hash_vector(v);
557  }
558 };
559 
560 template <>
561 struct hash<tlp::Vec3d> {
562  inline std::size_t operator()(const tlp::Vec3f &v) const {
563  return hash_vector(v);
564  }
565 };
566 
567 template <>
568 struct hash<tlp::Vec4d> {
569  inline std::size_t operator()(const tlp::Vec4d &v) const {
570  return hash_vector(v);
571  }
572 };
573 
574 template <>
575 struct hash<tlp::Vec2f> {
576  inline std::size_t operator()(const tlp::Vec2f &v) const {
577  return hash_vector(v);
578  }
579 };
580 
581 template <>
582 struct hash<tlp::Vec3f> {
583  inline std::size_t operator()(const tlp::Vec3f &v) const {
584  return hash_vector(v);
585  }
586 };
587 
588 template <>
589 struct hash<tlp::Vec4f> {
590  inline std::size_t operator()(const tlp::Vec4f &v) const {
591  return hash_vector(v);
592  }
593 };
594 } // namespace std
595 
596 #include "cxx/Vector.cxx"
597 
598 // fix for bug #3598871: allow use of VECTOR keyword in other software
599 #undef VECTOR
600 #undef TEMPLATEVECTOR
601 
602 #endif // TLP_VECTOR_H
603 ///@endcond