Easy3D 2.6.1
Loading...
Searching...
No Matches
vec.h
1/********************************************************************
2 * Copyright (C) 2015-2021 by Liangliang Nan <liangliang.nan@gmail.com>
3 * Copyright (C) 2000-2005 INRIA - Project ALICE
4 *
5 * The code in this file is partly from OGF/Graphite (2.0 alpha-4) with
6 * modifications and enhancement:
7 * https://gforge.inria.fr/forum/forum.php?forum_id=11459
8 * The original code was distributed under the GNU GPL license.
9 ********************************************************************/
10
11#ifndef EASY3D_CORE_VEC_H
12#define EASY3D_CORE_VEC_H
13
14#include <cassert>
15#include <iostream>
16#include <cmath>
17#include <cstring>
18#include <limits>
19
20
21namespace easy3d {
22
29 template <size_t N, class T>
30 class Vec {
31 public:
35
37 Vec() { for (size_t i = 0; i < N; i++) { data_[i] = T(0); } }
38
41 explicit Vec(const T& s) { for (size_t i = 0; i < N; i++) { data_[i] = s; } }
42
44 // This one should never be called : a template constructor cannot be a copy constructor
45 template<class T2> explicit Vec(const Vec<N, T2>& rhs) {
46 for (size_t i = 0; i < N; i++) {
47 data_[i] = T(rhs[i]);
48 }
49 }
50
52 // to avoid compilation problems
53 template<class T2, size_t M> explicit Vec(const Vec<M, T2>& rhs) {
54 assert(M == N);
55 for (size_t i = 0; i < N; i++) {
56 data_[i] = T(rhs[i]);
57 }
58 }
59
61 template<class T2> explicit Vec(const T2* rhs) {
62 for (size_t i = 0; i < N; i++) {
63 data_[i] = T(rhs[i]);
64 }
65 }
66
69 // Check for self-assignment
70 if (this == &rhs)
71 return *this; // Return *this if rhs is the same as *this
72 memcpy(data_, rhs.data(), N*sizeof(T));
73 return *this;
74 }
75
77 static size_t dimension() { return (size_t)N; }
79 static size_t size() { return (size_t)N; }
80
82 T* data() { return data_; }
84 const T* data() const { return data_; }
85
88 operator const T*() const { return data_; }
91 operator T*() { return data_; }
92
93 // Liangliang: The compiler can't decide whether to use your overloaded
94 // operator[] or the built-in operator[] on the const T*.
95 // See https://stackoverflow.com/questions/1726740/c-error-operator-2-overloads-have-similar-conversions
96 //T& operator[](size_t idx) {
97 // assert(idx < N);
98 // return data()[idx];
99 //}
100 //const T& operator[](size_t idx) const {
101 // assert(idx < N);
102 // return data()[idx];
103 //}
104
106 T length2() const {
107 T result = T(0);
108 for (size_t i = 0; i < N; i++) {
109 result += data_[i] * data_[i];
110 }
111 return result;
112 }
113
115 T length() const {
116 return std::sqrt(length2());
117 }
118
120 T norm() const {
121 return length();
122 }
123
125 T distance2(const thisclass &rhs) const {
126 T result = T(0);
127 for (size_t i = 0; i < N; i++) {
128 T val = rhs.data_[i] - data_[i];
129 result += val*val;
130 }
131 return result;
132 }
133
136 T s = length();
137 s = (s > std::numeric_limits<T>::min()) ? T(1.0) / s : T(0.0);
138 *this *= s;
139 return *this;
140 }
141
144 for (size_t i = 0; i < N; i++) {
145 data_[i] += v.data_[i];
146 }
147 return *this;
148 }
149
152 for (size_t i = 0; i < N; i++) {
153 data_[i] -= v.data_[i];
154 }
155 return *this;
156 }
157
160 for (size_t i = 0; i < N; i++) {
161 data_[i] *= v.data_[i];
162 }
163 return *this;
164 }
165
168 for (size_t i = 0; i < N; i++) {
169 data_[i] /= v.data_[i];
170 }
171 return *this;
172 }
173
175 template <class T2> thisclass& operator*=(T2 s) {
176 for (size_t i = 0; i < N; i++) {
177 data_[i] *= T(s);
178 }
179 return *this;
180 }
181
183 template <class T2> thisclass& operator/=(T2 s) {
184 for (size_t i = 0; i < N; i++) {
185 data_[i] /= T(s);
186 }
187 return *this;
188 }
189
192 thisclass result(*this);
193 for (size_t i = 0; i < N; i++) {
194 result.data_[i] += v.data_[i];
195 }
196 return result;
197 }
198
201 thisclass result(*this);
202 for (size_t i = 0; i < N; i++) {
203 result.data_[i] -= v.data_[i];
204 }
205 return result;
206 }
207
209 template <class T2> thisclass operator* (T2 s) const {
210 thisclass result(*this);
211 for (size_t i = 0; i < N; i++) {
212 result.data_[i] *= T(s);
213 }
214 return result;
215 }
216
218 template <class T2> thisclass operator/ (T2 s) const {
219 thisclass result(*this);
220 for (size_t i = 0; i < N; i++) {
221 result.data_[i] /= T(s);
222 }
223 return result;
224 }
225
228 thisclass result;
229 for (size_t i = 0; i < N; i++) {
230 result.data_[i] = -data_[i];
231 }
232 return result;
233 }
234
235
236 private:
237 T data_[N];
238 };
239
240
242 template <size_t N, class T> T dot(const Vec<N, T>& v1, const Vec<N, T>& v2) {
243 T result = 0;
244 for (size_t i = 0; i < N; i++) {
245 result += v1[i] * v2[i];
246 }
247 return result;
248 }
249
251 template <size_t N, class T> Vec<N, T> operator-(const Vec<N, T>& v1) {
252 Vec<N, T> result;
253 for (size_t i = 0; i < N; i++) {
254 result[i] = -v1[i];
255 }
256 return result;
257 }
258
260 template <class T2, size_t N, class T> Vec<N, T> operator*(T2 s, const Vec<N, T>& v) {
261 Vec<N, T> result;
262 for (size_t i = 0; i < N; i++) {
263 result[i] = T(s)*v[i];
264 }
265 return result;
266 }
267
269 template <size_t N, class T> Vec<N, T> operator+(const Vec<N, T>& v1, const Vec<N, T>& v2) {
270 Vec<N, T> result;
271 for (size_t i = 0; i < N; i++) {
272 result[i] = v1[i] + v2[i];
273 }
274 return result;
275 }
276
278 template <size_t N, class T> Vec<N, T> operator-(const Vec<N, T>& v1, const Vec<N, T>& v2) {
279 Vec<N, T> result;
280 for (size_t i = 0; i < N; i++) {
281 result[i] = v1[i] - v2[i];
282 }
283 return result;
284 }
285
286 // Global functions for vectors (compatible with GLSL)
287
289 template <size_t N, class T> T length(const Vec<N, T>& v) { return v.length(); }
291 template <size_t N, class T> T norm(const Vec<N, T>& v) { return v.length(); }
293 template <size_t N, class T> T length2(const Vec<N, T>& v) { return v.length2(); }
295 template <size_t N, class T> T distance(const Vec<N, T>& v1, const Vec<N, T>& v2) { return length(v2 - v1); }
297 template <size_t N, class T> T distance2(const Vec<N, T>& v1, const Vec<N, T>& v2) { return v2.distance2(v1); }
299 template <size_t N, class T> Vec<N, T> normalize(const Vec<N, T>& v) {
300 T s = v.length();
301 s = (s > std::numeric_limits<T>::min()) ? T(1.0) / s : T(0.0);
302 return v * s;
303 }
304
307 template <size_t N, class T> Vec<N, T> mix(const Vec<N, T>& v1, const Vec<N, T>& v2, T w) {
308 return (T(1) - w) * v1 + w * v2;
309 }
310
311 //-------------------- vec2 -------------------------------------------------------------------
312
318 template <class T>
319 class Vec<2, T> {
320 public:
323 typedef Vec<2, T> thisclass;
324
326 Vec() : x(0), y(0) { }
327
331 Vec(T x_in, T y_in) : x(x_in), y(y_in) { }
332
335 explicit Vec(const Vec<3, T>& v) : x(v.x), y(v.y) { }
336
339 explicit Vec(const T& s) : x(s), y(s) { }
340
344 template<class T2> explicit Vec(const Vec<2, T2> & v)
345 : x(v.x), y(v.y) {}
346
350 template<class T2> explicit Vec(const T2* v)
351 : x(T(v[0])), y(T(v[1])) {}
352
355 T length2() const { return x*x + y*y; }
356
359 T length() const { return std::sqrt(x*x + y*y); }
360
363 T norm() const { return length(); }
364
368 T distance2(const thisclass& rhs) const {
369 T dx = rhs.x - x;
370 T dy = rhs.y - y;
371 return dx*dx + dy*dy;
372 }
373
377 T s = length();
378 s = (s > std::numeric_limits<T>::min()) ? T(1.0) / s : T(0.0);
379 *this *= s;
380 return *this;
381 }
382
386 thisclass& operator+=(const thisclass& v) { x += v.x; y += v.y; return *this; }
390 thisclass& operator-=(const thisclass& v) { x -= v.x; y -= v.y; return *this; }
394 thisclass& operator*=(const thisclass& v) { x *= v.x; y *= v.y; return *this; }
398 thisclass& operator/=(const thisclass& v) { x /= v.x; y /= v.y; return *this; }
403 template <class T2> thisclass& operator*=(T2 s) { x *= T(s); y *= T(s); return *this; }
408 template <class T2> thisclass& operator/=(T2 s) { x /= T(s); y /= T(s); return *this; }
409
413 thisclass operator+ (const thisclass& v) const { return thisclass(x + v.x, y + v.y); }
417 thisclass operator- (const thisclass& v) const { return thisclass(x - v.x, y - v.y); }
418
423 template <class T2> thisclass operator* (T2 s) const { return thisclass(x*T(s), y*T(s)); }
428 template <class T2> thisclass operator/ (T2 s) const { return thisclass(x / T(s), y / T(s)); }
429
432 thisclass operator- () const { return thisclass(-x, -y); }
433
436 static size_t dimension() { return (size_t)2; }
439 static size_t size() { return (size_t)2; }
440
443 T* data() { return _array; }
446 const T* data() const { return _array; }
447
451 operator const T*() const { return _array; }
455 operator T*() { return _array; }
456
457 // Liangliang: The compiler can't decide whether to use your overloaded
458 // operator[] or the built-in operator[] on the const T*.
459 // See https://stackoverflow.com/questions/1726740/c-error-operator-2-overloads-have-similar-conversions
460 //T& operator[](size_t idx) {
461 // assert(idx < 2);
462 // return _array[idx];
463 //}
464 //const T& operator[](size_t idx) const {
465 // assert(idx < 2);
466 // return _array[idx];
467 //}
468
470 union {
471 T _array[2];
472 struct { T x, y; };
473 struct { T u, v; };
474 };
475 };
476
478 template <class T> T dot(const Vec<2, T>& v1, const Vec<2, T>& v2) { return v1.x*v2.x + v1.y*v2.y; }
479
481 template <class T> T det(const Vec<2, T>& v1, const Vec<2, T>& v2) {
482 return v1.x*v2.y - v1.y*v2.x;
483 }
484
486 template <class T> Vec<2, T> operator-(const Vec<2, T>& v1) {
487 return Vec<2, T>(-v1.x, -v1.y);
488 }
489
491 template <class T2, class T> Vec<2, T> operator*(T2 s, const Vec<2, T>& v) {
492 return Vec<2, T>(T(s)*v.x, T(s)*v.y);
493 }
494
496 template <class T> Vec<2, T> operator+(const Vec<2, T>& v1, const Vec<2, T>& v2) {
497 return Vec<2, T>(v1.x + v2.x, v1.y + v2.y);
498 }
499
501 template <class T> Vec<2, T> operator-(const Vec<2, T>& v1, const Vec<2, T>& v2) {
502 return Vec<2, T>(v1.x - v2.x, v1.y - v2.y);
503 }
504
505
506 //---------------- vec3 ------------------------------------------------------------------------
507
513 template <class T>
514 class Vec<3, T> {
515 public:
518 typedef Vec<3, T> thisclass;
519
521 Vec() : x(0), y(0), z(0) {}
522
526 explicit Vec(const Vec<2, T>& v, const T& s = 1) : x(v.x), y(v.y), z(s) {}
527
530 explicit Vec(const Vec<4, T>& v) : x(v.x), y(v.y), z(v.z) {}
531
536 Vec(T x_in, T y_in, T z_in) : x(x_in), y(y_in), z(z_in) {}
537
540 explicit Vec(const T& s) : x(s), y(s), z(s) { }
541
545 template<class T2> explicit Vec(const Vec<3, T2> & v) : x(v.x), y(v.y), z(v.z) {}
546
550 template<class T2> explicit Vec(const T2* v)
551 : x(T(v[0])), y(T(v[1])), z(T(v[2])) {}
552
555 T length2() const { return x*x + y*y + z*z; }
558 T length() const { return std::sqrt(x*x + y*y + z*z); }
561 T norm() const { return length(); }
565 T distance2(const thisclass& rhs) const {
566 T dx = rhs.x - x;
567 T dy = rhs.y - y;
568 T dz = rhs.z - z;
569 return dx*dx + dy*dy + dz*dz;
570 }
571
575 T s = length();
576 s = (s > std::numeric_limits<T>::min()) ? T(1.0) / s : T(0.0);
577 *this *= s;
578 return *this;
579 }
580
584 thisclass& operator+=(const thisclass& v) { x += v.x; y += v.y; z += v.z; return *this; }
588 thisclass& operator-=(const thisclass& v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
592 thisclass& operator*=(const thisclass& v) { x *= v.x; y *= v.y; z *= v.z; return *this; }
596 thisclass& operator/=(const thisclass& v) { x /= v.x; y /= v.y; z /= v.z; return *this; }
601 template <class T2> thisclass& operator*=(T2 s) { x *= T(s); y *= T(s); z *= T(s); return *this; }
606 template <class T2> thisclass& operator/=(T2 s) { x /= T(s); y /= T(s); z /= T(s); return *this; }
607
611 thisclass operator+ (const thisclass& v) const { return thisclass(x + v.x, y + v.y, z + v.z); }
615 thisclass operator- (const thisclass& v) const { return thisclass(x - v.x, y - v.y, z - v.z); }
616
621 template <class T2> thisclass operator* (T2 s) const { return thisclass(x*T(s), y*T(s), z*T(s)); }
626 template <class T2> thisclass operator/ (T2 s) const { return thisclass(x / T(s), y / T(s), z / T(s)); }
627
630 thisclass operator- () const { return thisclass(-x, -y, -z); }
631
634 static size_t dimension() { return (size_t)3; }
637 static size_t size() { return (size_t)3; }
638
641 T* data() { return _array; }
644 const T* data() const { return _array; }
645
648 Vec<2, T> xy() const { return Vec<2, T>(x, y); }
649
653 operator const T*() const { return _array; }
657 operator T*() { return _array; }
658
659 // Liangliang: The compiler can't decide whether to use your overloaded
660 // operator[] or the built-in operator[] on the const T*.
661 // See https://stackoverflow.com/questions/1726740/c-error-operator-2-overloads-have-similar-conversions
662 //T& operator[](size_t idx) {
663 // assert(idx < 3);
664 // return _array[idx];
665 //}
666 //const T& operator[](size_t idx) const {
667 // assert(idx < 3);
668 // return _array[idx];
669 //}
670
672 union {
673 T _array[3];
674 struct { T x, y, z; };
675 struct { T r, g, b; };
676 };
677 };
678
680 template <class T> T dot(const Vec<3, T>& v1, const Vec<3, T>& v2) {
681 return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
682 }
683
685 template <class T> Vec<3, T> cross(const Vec<3, T>& v1, const Vec<3, T>& v2) {
686 return Vec<3, T>(
687 v1.y*v2.z - v1.z*v2.y,
688 v1.z*v2.x - v1.x*v2.z,
689 v1.x*v2.y - v1.y*v2.x
690 );
691 }
692
694 template <class T> Vec<3, T> operator-(const Vec<3, T>& v1) { return Vec<3, T>(-v1.x, -v1.y, -v1.z); }
695
697 template <class T2, class T> Vec<3, T> operator*(T2 s, const Vec<3, T>& v) {
698 return Vec<3, T>(T(s)*v.x, T(s)*v.y, T(s)*v.z);
699 }
700
702 template <class T> Vec<3, T> operator+(const Vec<3, T>& v1, const Vec<3, T>& v2) {
703 return Vec<3, T>(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
704 }
705
707 template <class T> Vec<3, T> operator-(const Vec<3, T>& v1, const Vec<3, T>& v2) {
708 return Vec<3, T>(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
709 }
710
712 template <class T> Vec<3, T> orthogonal(const Vec<3, T>& v) {
713 T absx = std::fabs(v.x);
714 T absy = std::fabs(v.y);
715 T absz = std::fabs(v.z);
716 // Find the smallest component. Keep equal case for null values.
717 if ((absy >= absx) && (absz >= absx))
718 return Vec<3, T>(0.0f, -v.z, v.y);
719 else
720 if ((absx >= absy) && (absz >= absy))
721 return Vec<3, T>(-v.z, 0.0f, v.x);
722 else
723 return Vec<3, T>(-v.y, v.x, 0.0f);
724 }
725
726 // ----------------- vec4 ----------------------------------------------------------------------------------
727
733 template <class T>
734 class Vec<4, T> {
735 public:
738 typedef Vec<4, T> thisclass;
739
741 Vec() : x(0), y(0), z(0), w(0) {}
742
746 explicit Vec(const Vec<3, T>& v, const T& s = 1) : x(v.x), y(v.y), z(v.z), w(s) {}
747
753 Vec(T x_in, T y_in, T z_in, T w_in) : x(x_in), y(y_in), z(z_in), w(w_in) {}
754
757 explicit Vec(const T& s) : x(s), y(s), z(s), w(s) { }
758
762 template<class T2> explicit Vec(const Vec<4, T2> & v)
763 : x(v.x), y(v.y), z(v.z), w(v.w) {}
764
768 template<class T2> explicit Vec(const T2* v)
769 : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
770
773 T length2() const { return x*x + y*y + z*z + w*w; }
776 T length() const { return std::sqrt(x*x + y*y + z*z + w*w); }
779 T norm() const { return length(); }
783 T distance2(const thisclass& rhs) const {
784 T dx = rhs.x - x;
785 T dy = rhs.y - y;
786 T dz = rhs.z - z;
787 T dw = rhs.w - w;
788 return dx*dx + dy*dy + dz*dz + dw*dw;
789 }
790
794 T s = length();
795 s = (s > std::numeric_limits<T>::min()) ? T(1.0) / s : T(0.0);
796 *this *= s;
797 return *this;
798 }
799
802 static size_t dimension() { return (size_t)4; }
805 static size_t size() { return (size_t)4; }
806
810 thisclass& operator+=(const thisclass& v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; }
814 thisclass& operator-=(const thisclass& v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; return *this; }
818 thisclass& operator*=(const thisclass& v) { x *= v.x; y *= v.y; z *= v.z; w *= v.w; return *this; }
822 thisclass& operator/=(const thisclass& v) { x /= v.x; y /= v.y; z /= v.z; w /= v.w; return *this; }
823
828 template <class T2> thisclass& operator*=(T2 s) {
829 x *= T(s); y *= T(s); z *= T(s); w *= T(s); return *this;
830 }
835 template <class T2> thisclass& operator/=(T2 s) {
836 x /= T(s); y /= T(s); z /= T(s); w /= T(s); return *this;
837 }
838
842 thisclass operator+ (const thisclass& v) const { return thisclass(x + v.x, y + v.y, z + v.z, w + v.w); }
846 thisclass operator- (const thisclass& v) const { return thisclass(x - v.x, y - v.y, z - v.z, w - v.w); }
847
852 template <class T2> thisclass operator* (T2 s) const { return thisclass(x*T(s), y*T(s), z*T(s), w*T(s)); }
857 template <class T2> thisclass operator/ (T2 s) const { return thisclass(x / T(s), y / T(s), z / T(s), w / T(s)); }
858
861 thisclass operator- () const { return thisclass(-x, -y, -z, -w); }
862
865 T* data() { return _array; }
868 const T* data() const { return _array; }
869
872 Vec<3, T> xyz() const { return Vec<3, T>(x, y, z); }
873
877 operator const T*() const { return _array; }
881 operator T*() { return _array; }
882
883 // Liangliang: The compiler can't decide whether to use your overloaded
884 // operator[] or the built-in operator[] on the const T*.
885 // See https://stackoverflow.com/questions/1726740/c-error-operator-2-overloads-have-similar-conversions
886 //T& operator[](size_t idx) {
887 // assert(idx < 4);
888 // return _array[idx];
889 //}
890 //const T& operator[](size_t idx) const {
891 // assert(idx < 4);
892 // return _array[idx];
893 //}
894
896 union {
897 T _array[4];
898 struct { T x, y, z, w; };
899 struct { T r, g, b, a; };
900 };
901 };
902
904 template <class T> T dot(const Vec<4, T>& v1, const Vec<4, T>& v2) {
905 return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w;
906 }
907
909 template <class T> Vec<4, T> operator-(const Vec<4, T>& v1) { return Vec<4, T>(-v1.x, -v1.y, -v1.z, -v1.w); }
910
912 template <class T2, class T> Vec<4, T> operator*(T2 s, const Vec<4, T>& v) {
913 return Vec<4, T>(T(s)*v.x, T(s)*v.y, T(s)*v.z, T(s)*v.w);
914 }
915
917 template <class T> Vec<4, T> operator+(const Vec<4, T>& v1, const Vec<4, T>& v2) {
918 return Vec<4, T>(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w);
919 }
920
922 template <class T> Vec<4, T> operator-(const Vec<4, T>& v1, const Vec<4, T>& v2) {
923 return Vec<4, T>(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w);
924 }
925
926
927
928 //------------------------------- IO (input/output) ----------------------------
929
931 template <size_t N, class T> std::ostream& operator<<(std::ostream& out, const Vec<N, T>& v) {
932 for (size_t i = 0; i < N; i++) {
933 out << v[i] << " ";
934 }
935 return out;
936 }
937
939 template <size_t N, class T> std::istream& operator>>(std::istream& in, Vec<N, T>& v) {
940 for (size_t i = 0; i < N; i++) {
941 in >> v[i];
942 }
943 return in;
944 }
945
947 template <class T> std::ostream& operator<<(std::ostream& out, const Vec<2, T>& v) {
948 return out << v.x << " " << v.y;
949 }
950
952 template <class T> std::istream& operator>>(std::istream& in, Vec<2, T>& v) {
953 return in >> v.x >> v.y;
954 }
955
957 template <class T> std::ostream& operator<<(std::ostream& out, const Vec<3, T>& v) {
958 return out << v.x << " " << v.y << " " << v.z;
959 }
960
962 template <class T> std::istream& operator>>(std::istream& in, Vec<3, T>& v) {
963 return in >> v.x >> v.y >> v.z;
964 }
965
967 template <class T> std::ostream& operator<<(std::ostream& out, const Vec<4, T>& v) {
968 return out << v.x << " " << v.y << " " << v.z << " " << v.w;
969 }
970
972 template <class T> std::istream& operator>>(std::istream& in, Vec<4, T>& v) {
973 return in >> v.x >> v.y >> v.z >> v.w;
974 }
975
976 //----------------------------------------------------------------------
977
979 template <size_t N, class T>
980 bool has_nan(const Vec<N, T> &v) {
981 for (std::size_t i = 0; i < N; ++i) {
982 if (std::isnan(v[i]) || std::isinf(v[i]))
983 return true;
984 }
985 return false;
986 }
987
989 template <size_t N, class T>
990 bool operator==(const Vec<N,T> &a, const Vec<N,T> &b) {
991 for (size_t i = 0; i < N; i++) {
992 if (a[i] != b[i]) return false;
993 }
994 return true;
995 }
996
998 template <size_t N, class T>
999 bool operator!=(const Vec<N,T> &a, const Vec<N,T> &b) {
1000 for (size_t i = 0; i < N; i++) {
1001 if (a[i] != b[i]) return true;
1002 }
1003 return false;
1004 }
1005
1007 template <size_t N, class T>
1008 bool operator<(const Vec<N,T> &a, const Vec<N,T> &b) {
1009 for(unsigned int i=0; i<N; ++i){
1010 if(a[i]<b[i]) return true;
1011 if(a[i]>b[i]) return false;
1012 }
1013 return false;
1014 }
1015
1017 template <size_t N, class T>
1019 Vec<N, T> result;
1020 for (int i = 0; i < N; ++i)
1021 result[i] = v1[i] * v2[i];
1022 return result;
1023 }
1024
1026 template <size_t N, class T>
1027 Vec<N, T> comp_min(const Vec<N, T> &v1, const Vec<N, T> &v2) {
1028 Vec<N, T> result;
1029 for (int i = 0; i < N; ++i)
1030 result[i] = std::min(v1[i], v2[i]);
1031 return result;
1032 }
1033
1035 template <size_t N, class T>
1036 Vec<N, T> comp_max(const Vec<N, T> &v1, const Vec<N, T> &v2) {
1037 Vec<N, T> result;
1038 for (int i = 0; i < N; ++i)
1039 result[i] = std::max(v1[i], v2[i]);
1040 return result;
1041 }
1042
1044 template<size_t N, class T>
1045 T min_coord(const Vec<N, T> &a) {
1046 T result = a[0];
1047 for (unsigned int i = 1; i < N; ++i) if (a[i] < result) result = a[i];
1048 return result;
1049 }
1050
1052 template<size_t N, class T>
1053 T max_coord(const Vec<N, T> &a) {
1054 T result = a[0];
1055 for (unsigned int i = 1; i < N; ++i) if (a[i] > result) result = a[i];
1056 return result;
1057 }
1058
1060 template<size_t N, class T>
1061 Vec<N, T> clamp(const Vec<N, T> &a, const Vec<N, T> &lower, const Vec<N, T> &upper) {
1062 Vec<N, T> result;
1063 for (unsigned int i = 0; i < N; ++i) result[i] = std::min(upper[i], std::max(a[i], lower[i]));
1064 return result;
1065 }
1066
1067}
1068
1069#endif // EASY3D_CORE_VEC_H
1070
Base class for vector types. It provides generic functionality for N dimensional vectors.
Definition vec.h:30
Vec< N, FT > thisclass
Definition vec.h:34
static size_t size()
Returns the dimension/size of this vector.
Definition vec.h:79
thisclass & operator*=(T2 s)
Compound vector-scalar multiplication.
Definition vec.h:175
thisclass & operator/=(T2 s)
Compound vector-scalar division.
Definition vec.h:183
static size_t dimension()
Returns the dimension/size of this vector.
Definition vec.h:77
thisclass & operator+=(const thisclass &v)
Compound addition with another vector.
Definition vec.h:143
T length() const
Returns the length of this vector.
Definition vec.h:115
thisclass operator/(T2 s) const
Vector-scalar division.
Definition vec.h:218
thisclass & operator*=(const thisclass &v)
Compound component-wise multiplication with another vector.
Definition vec.h:159
const T * data() const
Returns the constant memory address of the vector.
Definition vec.h:84
thisclass operator*(T2 s) const
Vector-scalar multiplication.
Definition vec.h:209
thisclass & operator/=(const thisclass &v)
Compound component-wise division with another vector.
Definition vec.h:167
Vec(const T &s)
Constructs a vector from a scalar number.
Definition vec.h:41
Vec()
Default constructor. All elements will be initialized to zero.
Definition vec.h:37
thisclass & operator-=(const thisclass &v)
Compound subtraction with another vector.
Definition vec.h:151
thisclass operator-() const
Negates this vector (i.e., adds a minus sign).
Definition vec.h:227
thisclass operator+(const thisclass &v) const
Addition with another vector.
Definition vec.h:191
Vec(const Vec< N, T2 > &rhs)
Constructs a vector from another vector of the same dimension/size.
Definition vec.h:45
Vec(const Vec< M, T2 > &rhs)
Constructs a vector from another vector of the same dimension/size.
Definition vec.h:53
T distance2(const thisclass &rhs) const
Returns the squared Euclidean distance to another vector.
Definition vec.h:125
thisclass & normalize()
Normalizes this vector.
Definition vec.h:135
T norm() const
Returns the norm (i.e., length/magnitude) of this vector.
Definition vec.h:120
thisclass & operator=(const thisclass &rhs)
Assignment operator. It assigns the value of this vector from another vector.
Definition vec.h:68
T * data()
Returns the memory address of the vector.
Definition vec.h:82
Vec(const T2 *rhs)
Constructs a vector from an array of values.
Definition vec.h:61
T length2() const
Returns the squared length of this vector.
Definition vec.h:106
Definition collider.cpp:182
Matrix< FT > operator+(const Matrix< FT > &, const FT &)
Definition matrix.h:1010
Matrix< FT > operator-(const Matrix< FT > &)
arithmetic operators
Definition matrix.h:995
bool operator!=(const Vec< N, T > &a, const Vec< N, T > &b)
Test if two vectors are strictly not identical.
Definition vec.h:999
T distance(const Vec< N, T > &v1, const Vec< N, T > &v2)
Computes the distance between two vectors/points.
Definition vec.h:295
Vec< N, T > comp_min(const Vec< N, T > &v1, const Vec< N, T > &v2)
Component-wise minimum vector.
Definition vec.h:1027
Vec< N, T > normalize(const Vec< N, T > &v)
Computes and returns the normalized vector (Note: the input vector is not modified).
Definition vec.h:299
Vec< N, T > comp_max(const Vec< N, T > &v1, const Vec< N, T > &v2)
Component-wise maximum vector.
Definition vec.h:1036
T length(const Vec< N, T > &v)
Computes the length/magnitude of a vector.
Definition vec.h:289
T clamp(T x, T lower, T upper)
Clamps a num to be within a given range.
Definition types.h:129
Vec< 3, T > cross(const Vec< 3, T > &v1, const Vec< 3, T > &v2)
Compute the cross product of two 3D vectors.
Definition vec.h:685
Vec< 3, T > orthogonal(const Vec< 3, T > &v)
Compute a vector that is orthogonal to the given vector.
Definition vec.h:712
std::ostream & operator<<(std::ostream &os, Graph::Vertex v)
Output stream support for Graph::Vertex.
Definition graph.h:1300
bool operator<(const Vec< N, T > &a, const Vec< N, T > &b)
Lexicographic comparison of two vectors.
Definition vec.h:1008
T det(const Vec< 2, T > &v1, const Vec< 2, T > &v2)
Compute the determinant of the 2x2 matrix formed by the two 2D vectors as the two rows.
Definition vec.h:481
T length2(const Vec< N, T > &v)
Computes the squared length/magnitude of a vector.
Definition vec.h:293
bool operator==(const Vec< N, T > &a, const Vec< N, T > &b)
Test if two vectors are strictly identical.
Definition vec.h:990
T distance2(const Vec< N, T > &v1, const Vec< N, T > &v2)
Computes the squared distance between two vectors/points.
Definition vec.h:297
std::istream & operator>>(std::istream &is, GenericLine< DIM, FT > &line)
Input stream support for GenericLine.
Definition line.h:183
T max_coord(const Vec< N, T > &a)
The maximum coordinate of elements in a vector.
Definition vec.h:1053
Vec< N, T > mix(const Vec< N, T > &v1, const Vec< N, T > &v2, T w)
Definition vec.h:307
bool has_nan(const GenericBox< DIM, FT > &box)
Check if the representation of a box has NaN.
Definition box.h:373
T min_coord(const Vec< N, T > &a)
The minimum coordinate of elements in a vector.
Definition vec.h:1045
FT dot(const std::vector< FT > &, const std::vector< FT > &)
Inner product for vectors.
Definition matrix.h:1834
Vec< N, T > comp_product(const Vec< N, T > &v1, const Vec< N, T > &v2)
Component-wise product of two vectors.
Definition vec.h:1018
FT norm(const Matrix< FT > &)
utilities
Definition matrix.h:1455
Mat< N, M, T > operator*(T lhs, const Mat< N, M, T > &rhs)
Multiplies a scalar by a matrix.
Definition mat.h:1000