Tulip 5.7.1
Large graphs analysis and drawing
Loading...
Searching...
No Matches
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
35namespace tlp {
36
37template <typename TYPE, typename OTYPE>
38inline OTYPE tlpsqr(const TYPE a) {
39 return static_cast<OTYPE>(a) * static_cast<OTYPE>(a);
40}
41
42template <typename TYPE, typename OTYPE>
43inline TYPE tlpsqrt(const OTYPE a) {
44 return static_cast<TYPE>(sqrt(a));
45}
46
47template <>
48inline 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 */
65template <typename TYPE, size_t SIZE, typename OTYPE = double, typename DTYPE = TYPE>
66class Vector : public Array<TYPE, SIZE> {
67public:
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
359TEMPLATEVECTOR
360inline TYPE dotProduct(const VECTOR &a, const VECTOR &b) {
361 return a.dotProduct(b);
362}
363
364TEMPLATEVECTOR
365inline 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 */
374TEMPLATEVECTOR
375inline 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 */
388TEMPLATEVECTOR
389inline 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 */
401TEMPLATEVECTOR
402inline 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
414TEMPLATEVECTOR
415inline VECTOR operator*(const VECTOR &, const VECTOR &);
416TEMPLATEVECTOR
417inline VECTOR operator*(const TYPE, const VECTOR &);
418TEMPLATEVECTOR
419inline VECTOR operator*(const VECTOR &, const TYPE);
420
421TEMPLATEVECTOR
422inline VECTOR operator+(const VECTOR &, const VECTOR &);
423TEMPLATEVECTOR
424inline VECTOR operator+(const VECTOR &, const TYPE);
425
426TEMPLATEVECTOR
427inline VECTOR operator-(const VECTOR &, const VECTOR &);
428TEMPLATEVECTOR
429inline VECTOR operator-(const VECTOR &, const TYPE);
430
431TEMPLATEVECTOR
432inline VECTOR operator/(const VECTOR &, const VECTOR &);
433TEMPLATEVECTOR
434inline VECTOR operator/(const VECTOR &, const TYPE);
435
436TEMPLATEVECTOR
437inline VECTOR operator^(const VECTOR &, const VECTOR &);
438TEMPLATEVECTOR
439inline VECTOR operator-(const VECTOR &);
440/**
441 * @brief typedef for 2D vector of unsigned int
442 */
443typedef Vector<unsigned int, 2> Vec2ui;
444/**
445 * @brief typedef for 3D vector of unsigned int
446 */
447typedef Vector<unsigned int, 3> Vec3ui;
448/**
449 * @brief typedef for 4D vector of unsigned int
450 */
451typedef Vector<unsigned int, 4> Vec4ui;
452/**
453 * @brief typedef for 2D vector of int
454 */
455typedef Vector<int, 2> Vec2i;
456/**
457 * @brief typedef for 3D vector of int
458 */
459typedef Vector<int, 3> Vec3i;
460/**
461 * @brief typedef for 4D vector of int
462 */
463typedef Vector<int, 4> Vec4i;
464/**
465 * @brief typedef for 2D vector of double
466 */
467typedef Vector<double, 2, long double> Vec2d;
468/**
469 * @brief typedef for 3D vector of double
470 */
471typedef Vector<double, 3, long double> Vec3d;
472/**
473 * @brief typedef for 4D vector of double
474 */
475typedef Vector<double, 4, long double> Vec4d;
476/**
477 * @brief typedef for 2D vector of float
478 */
479typedef Vector<float, 2, double> Vec2f;
480/**
481 * @brief typedef for 3D vector of float
482 */
483typedef Vector<float, 3, double> Vec3f;
484/**
485 * @brief typedef for 4D vector of float
486 */
487typedef Vector<float, 4, double> Vec4f;
488} // namespace tlp
489
490#ifdef _MSC_VER
491static double sqrt(tlp::Vector<float, 5> &v) {
492 return sqrt((double)v[0]);
493}
494
495template class TLP_SCOPE tlp::Vector<unsigned char, 4>;
496
497#endif
498
499namespace std {
500TEMPLATEVECTOR
501size_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
511template <>
512struct hash<tlp::Vec2ui> {
513 inline std::size_t operator()(const tlp::Vec2ui &v) const {
514 return hash_vector(v);
515 }
516};
517
518template <>
519struct hash<tlp::Vec3ui> {
520 inline std::size_t operator()(const tlp::Vec3ui &v) const {
521 return hash_vector(v);
522 }
523};
524
525template <>
526struct hash<tlp::Vec4ui> {
527 inline std::size_t operator()(const tlp::Vec4ui &v) const {
528 return hash_vector(v);
529 }
530};
531
532template <>
533struct hash<tlp::Vec2i> {
534 inline std::size_t operator()(const tlp::Vec2i &v) const {
535 return hash_vector(v);
536 }
537};
538
539template <>
540struct hash<tlp::Vec3i> {
541 inline std::size_t operator()(const tlp::Vec3i &v) const {
542 return hash_vector(v);
543 }
544};
545
546template <>
547struct hash<tlp::Vec4i> {
548 inline std::size_t operator()(const tlp::Vec4i &v) const {
549 return hash_vector(v);
550 }
551};
552
553template <>
554struct hash<tlp::Vec2d> {
555 inline std::size_t operator()(const tlp::Vec2d &v) const {
556 return hash_vector(v);
557 }
558};
559
560template <>
561struct hash<tlp::Vec3d> {
562 inline std::size_t operator()(const tlp::Vec3f &v) const {
563 return hash_vector(v);
564 }
565};
566
567template <>
568struct hash<tlp::Vec4d> {
569 inline std::size_t operator()(const tlp::Vec4d &v) const {
570 return hash_vector(v);
571 }
572};
573
574template <>
575struct hash<tlp::Vec2f> {
576 inline std::size_t operator()(const tlp::Vec2f &v) const {
577 return hash_vector(v);
578 }
579};
580
581template <>
582struct hash<tlp::Vec3f> {
583 inline std::size_t operator()(const tlp::Vec3f &v) const {
584 return hash_vector(v);
585 }
586};
587
588template <>
589struct 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