Vector4-Impl.h
Go to the documentation of this file.
1 /*************************************************************************
2 > File Name: Vector4-Impl.h
3 > Project Name: CubbyFlow
4 > Author: Dongmin Kim
5 > Purpose: 4-D vector class.
6 > Created Time: 2017/02/26
7 > Copyright (c) 2018, Dongmin Kim
8 *************************************************************************/
9 #ifndef CUBBYFLOW_VECTOR4_IMPL_H
10 #define CUBBYFLOW_VECTOR4_IMPL_H
11 
12 #include <Core/Math/MathUtils.h>
13 
14 #include <cassert>
15 
16 namespace CubbyFlow
17 {
18  // Constructors
19  template <typename T>
20  template <typename U>
21  Vector<T, 4>::Vector(const std::initializer_list<U>& list)
22  {
23  Set(list);
24  }
25 
26  template <typename T>
28  {
29  x = s;
30  y = s;
31  z = s;
32  w = s;
33  }
34 
35  template <typename T>
36  void Vector<T, 4>::Set(T newX, T newY, T newZ, T newW)
37  {
38  x = newX;
39  y = newY;
40  z = newZ;
41  w = newW;
42  }
43 
44  template <typename T>
45  void Vector<T, 4>::Set(const Vector<T, 3>& pt, T newW)
46  {
47  x = pt.x;
48  y = pt.y;
49  z = pt.z;
50  w = newW;
51  }
52 
53 
54  template <typename T>
55  template <typename U>
56  void Vector<T, 4>::Set(const std::initializer_list<U>& list)
57  {
58  assert(list.size() >= 4);
59 
60  auto inputElem = list.begin();
61  x = static_cast<T>(*inputElem);
62  y = static_cast<T>(*(++inputElem));
63  z = static_cast<T>(*(++inputElem));
64  w = static_cast<T>(*(++inputElem));
65  }
66 
67  template <typename T>
68  void Vector<T, 4>::Set(const Vector& v)
69  {
70  x = v.x;
71  y = v.y;
72  z = v.z;
73  w = v.w;
74  }
75 
76  template <typename T>
78  {
79  x = 0;
80  y = 0;
81  z = 0;
82  w = 0;
83  }
84 
85  template <typename T>
87  {
88  T length = Length();
89  x /= length;
90  y /= length;
91  z /= length;
92  w /= length;
93  }
94 
95  template <typename T>
97  {
98  return Vector(x + v, y + v, z + v, w + v);
99  }
100 
101  template <typename T>
103  {
104  return Vector(x + v.x, y + v.y, z + v.z, w + v.w);
105  }
106 
107  template <typename T>
109  {
110  return Vector(x - v, y - v, z - v, w - v);
111  }
112 
113  template <typename T>
115  {
116  return Vector(x - v.x, y - v.y, z - v.z, w - v.w);
117  }
118 
119  template <typename T>
121  {
122  return Vector(x * v, y * v, z * v, w * v);
123  }
124 
125  template <typename T>
127  {
128  return Vector(x * v.x, y * v.y, z * v.z, w * v.w);
129  }
130 
131  template <typename T>
133  {
134  return Vector(x / v, y / v, z / v, w / v);
135  }
136 
137  template <typename T>
139  {
140  return Vector(x / v.x, y / v.y, z / v.z, w / v.w);
141  }
142 
143  template <typename T>
144  T Vector<T, 4>::Dot(const Vector& v) const
145  {
146  return x * v.x + y * v.y + z * v.z + w * v.w;
147  }
148 
149  template <typename T>
151  {
152  return Vector(v - x, v - y, v - z, v - w);
153  }
154 
155  template <typename T>
157  {
158  return Vector(v.x - x, v.y - y, v.z - z, v.w - w);
159  }
160 
161  template <typename T>
163  {
164  return Vector(v / x, v / y, v / z, v / w);
165  }
166 
167  template <typename T>
169  {
170  return Vector(v.x / x, v.y / y, v.z / z, v.w / w);
171  }
172 
173  template <typename T>
175  {
176  x += v;
177  y += v;
178  z += v;
179  w += v;
180  }
181 
182  template <typename T>
183  void Vector<T, 4>::IAdd(const Vector& v)
184  {
185  x += v.x;
186  y += v.y;
187  z += v.z;
188  w += v.w;
189  }
190 
191  template <typename T>
193  {
194  x -= v;
195  y -= v;
196  z -= v;
197  w -= v;
198  }
199 
200  template <typename T>
201  void Vector<T, 4>::ISub(const Vector& v)
202  {
203  x -= v.x;
204  y -= v.y;
205  z -= v.z;
206  w -= v.w;
207  }
208 
209  template <typename T>
211  {
212  x *= v;
213  y *= v;
214  z *= v;
215  w *= v;
216  }
217 
218  template <typename T>
219  void Vector<T, 4>::IMul(const Vector& v)
220  {
221  x *= v.x;
222  y *= v.y;
223  z *= v.z;
224  w *= v.w;
225  }
226 
227  template <typename T>
229  {
230  x /= v;
231  y /= v;
232  z /= v;
233  w /= v;
234  }
235 
236  template <typename T>
237  void Vector<T, 4>::IDiv(const Vector& v)
238  {
239  x /= v.x;
240  y /= v.y;
241  z /= v.z;
242  w /= v.w;
243  }
244 
245  template <typename T>
246  const T& Vector<T, 4>::At(size_t i) const
247  {
248  assert(i < 4);
249  return (&x)[i];
250  }
251 
252  template <typename T>
253  T& Vector<T, 4>::At(size_t i)
254  {
255  assert(i < 4);
256  return (&x)[i];
257  }
258 
259  template <typename T>
261  {
262  return x + y + z + w;
263  }
264 
265  template <typename T>
267  {
268  return Sum() / 4;
269  }
270 
271  template <typename T>
273  {
274  return std::min({ x, y, z, w });
275  }
276 
277  template <typename T>
279  {
280  return std::max({ x, y, z, w });
281  }
282 
283  template <typename T>
285  {
287  }
288 
289  template <typename T>
291  {
293  }
294 
295  template <typename T>
297  {
298  return (std::fabs(x) > std::fabs(y))
299  ? ((std::fabs(x) > std::fabs(z))
300  ? ((std::fabs(x) > std::fabs(w)) ? 0 : 3)
301  : ((std::fabs(x) > std::fabs(w)) ? 2 : 3))
302  : ((std::fabs(y) > std::fabs(z))
303  ? ((std::fabs(y) > std::fabs(w)) ? 1 : 3)
304  : ((std::fabs(z) > std::fabs(w)) ? 2 : 3));
305  }
306 
307  template <typename T>
309  {
310  return (std::fabs(x) < std::fabs(y))
311  ? ((std::fabs(x) < std::fabs(z))
312  ? ((std::fabs(x) < std::fabs(w)) ? 0 : 3)
313  : ((std::fabs(x) < std::fabs(w)) ? 2 : 3))
314  : ((std::fabs(y) < std::fabs(z))
315  ? ((std::fabs(y) < std::fabs(w)) ? 1 : 3)
316  : ((std::fabs(z) < std::fabs(w)) ? 2 : 3));
317  }
318 
319  template <typename T>
321  {
322  return Vector(x / Length(), y / Length(), z / Length(), w / Length());
323  }
324 
325  template <typename T>
327  {
328  return std::sqrt(x * x + y * y + z * z + w * w);
329  }
330 
331  template <typename T>
333  {
334  return x * x + y * y + z * z + w * w;
335  }
336 
337  template <typename T>
339  {
340  return Sub(other).Length();
341  }
342 
343  template <typename T>
345  {
346  return Sub(other).LengthSquared();
347  }
348 
349  template <typename T>
350  template <typename U>
352  {
353  return Vector<U, 4>(static_cast<U>(x), static_cast<U>(y), static_cast<U>(z), static_cast<U>(w));
354  }
355 
356  template <typename T>
357  bool Vector<T, 4>::IsEqual(const Vector& other) const
358  {
359  return (x == other.x && y == other.y && z == other.z && w == other.w);
360  }
361 
362  template <typename T>
363  bool Vector<T, 4>::IsSimilar(const Vector& other, T epsilon) const
364  {
365  return (std::fabs(x - other.x) < epsilon) && (std::fabs(y - other.y) < epsilon && std::fabs(z - other.z) < epsilon) && (std::fabs(w - other.w) < epsilon);
366  }
367 
368  template <typename T>
370  {
371  assert(i < 4);
372  return (&x)[i];
373  }
374 
375  template <typename T>
376  const T& Vector<T, 4>::operator[](size_t i) const
377  {
378  assert(i < 4);
379  return At(i);
380  }
381 
382  template <typename T>
383  template <typename U>
384  Vector<T, 4>& Vector<T, 4>::operator=(const std::initializer_list<U>& list)
385  {
386  Set(list);
387  return (*this);
388  }
389 
390  template <typename T>
392  {
393  Set(v);
394  return (*this);
395  }
396 
397  template <typename T>
399  {
400  IAdd(v);
401  return (*this);
402  }
403 
404  template <typename T>
406  {
407  IAdd(v);
408  return (*this);
409  }
410 
411  template <typename T>
413  {
414  ISub(v);
415  return (*this);
416  }
417 
418  template <typename T>
420  {
421  ISub(v);
422  return (*this);
423  }
424 
425  template <typename T>
427  {
428  IMul(v);
429  return (*this);
430  }
431 
432  template <typename T>
434  {
435  IMul(v);
436  return (*this);
437  }
438 
439  template <typename T>
441  {
442  IDiv(v);
443  return (*this);
444  }
445 
446  template <typename T>
448  {
449  IDiv(v);
450  return (*this);
451  }
452 
453  template <typename T>
454  bool Vector<T, 4>::operator==(const Vector& v) const
455  {
456  return IsEqual(v);
457  }
458 
459  template <typename T>
460  bool Vector<T, 4>::operator!=(const Vector& v) const
461  {
462  return !IsEqual(v);
463  }
464 
465  template <typename T>
467  {
468  return a;
469  }
470 
471  template <typename T>
473  {
474  return Vector<T, 4>(-a.x, -a.y, -a.z, -a.w);
475  }
476 
477  template <typename T>
479  {
480  return a.Add(b);
481  }
482 
483  template <typename T>
485  {
486  return b.Add(a);
487  }
488 
489  template <typename T>
491  {
492  return a.Add(b);
493  }
494 
495  template <typename T>
497  {
498  return a.Sub(b);
499  }
500 
501  template <typename T>
503  {
504  return b.RSub(a);
505  }
506 
507  template <typename T>
509  {
510  return a.Sub(b);
511  }
512 
513  template <typename T>
515  {
516  return a.Mul(b);
517  }
518 
519  template <typename T>
521  {
522  return b.Mul(a);
523  }
524 
525  template <typename T>
527  {
528  return a.Mul(b);
529  }
530 
531  template <typename T>
533  {
534  return a.Div(b);
535  }
536 
537  template <typename T>
539  {
540  return b.RDiv(a);
541  }
542 
543  template <typename T>
545  {
546  return a.Div(b);
547  }
548 
549  template <typename T>
551  {
552  return Vector<T, 4>(std::min(a.x, b.x), std::min(a.y, b.y), std::min(a.z, b.z), std::min(a.w, b.w));
553  }
554 
555  template <typename T>
557  {
558  return Vector<T, 4>(std::max(a.x, b.x), std::max(a.y, b.y), std::max(a.z, b.z), std::max(a.w, b.w));
559  }
560 
561  template <typename T>
562  Vector<T, 4> Clamp(const Vector<T, 4>& v, const Vector<T, 4>& low, const Vector<T, 4>& high)
563  {
564  return Vector<T, 4>(Clamp(v.x, low.x, high.x), Clamp(v.y, low.y, high.y), Clamp(v.z, low.z, high.z), Clamp(v.w, low.w, high.w));
565  }
566 
567  template <typename T>
569  {
570  return Vector<T, 4>(std::ceil(a.x), std::ceil(a.y), std::ceil(a.z), std::ceil(a.w));
571  }
572 
573  template <typename T>
575  {
576  return Vector<T, 4>(std::floor(a.x), std::floor(a.y), std::floor(a.z), std::floor(a.w));
577  }
578 
579  template <typename T>
581  const Vector<T, 4>& v0,
582  const Vector<T, 4>& v1,
583  const Vector<T, 4>& v2,
584  const Vector<T, 4>& v3,
585  T f)
586  {
587  static const T two = static_cast<T>(2);
588  static const T three = static_cast<T>(3);
589 
590  Vector<T, 4> d1 = (v2 - v0) / two;
591  Vector<T, 4> d2 = (v3 - v1) / two;
592  Vector<T, 4> D1 = v2 - v1;
593 
594  if (std::fabs(D1.x) < std::numeric_limits<float>::epsilon() ||
595  Sign(D1.x) != Sign(d1.x) ||
596  Sign(D1.x) != Sign(d2.x))
597  {
598  d1.x = d2.x = 0;
599  }
600 
601  if (std::fabs(D1.y) < std::numeric_limits<float>::epsilon() ||
602  Sign(D1.y) != Sign(d1.y) ||
603  Sign(D1.y) != Sign(d2.y))
604  {
605  d1.y = d2.y = 0;
606  }
607 
608  if (std::fabs(D1.z) < std::numeric_limits<float>::epsilon() ||
609  Sign(D1.z) != Sign(d1.z) ||
610  Sign(D1.z) != Sign(d2.z))
611  {
612  d1.z = d2.z = 0;
613  }
614 
615  if (std::fabs(D1.w) < std::numeric_limits<float>::epsilon() ||
616  Sign(D1.w) != Sign(d1.w) ||
617  Sign(D1.w) != Sign(d2.w))
618  {
619  d1.w = d2.w = 0;
620  }
621 
622  Vector<T, 4> a3 = d1 + d2 - two * D1;
623  Vector<T, 4> a2 = three * D1 - two * d1 - d2;
624  Vector<T, 4> a1 = d1;
625  Vector<T, 4> a0 = v1;
626 
627  return a3 * Cubic(f) + a2 * Square(f) + a1 * f + a0;
628  }
629 }
630 
631 #endif
T Max() const
Returns the maximum element.
Definition: Vector-Impl.h:208
3-D vector class.
Definition: Vector3.h:26
T AbsMin(T x, T y)
Returns the absolute minimum value among the two inputs.
Definition: MathUtils-Impl.h:39
VectorScalarRDiv< T, Vector > RDiv(const T &s) const
Computes (s, s, ... , s) / this.
Definition: Vector-Impl.h:440
Vector Div(T v) const
Computes this / (v, v, v, v).
Definition: Vector4-Impl.h:132
T z
Z (or the third) component of the vector.
Definition: Vector3.h:38
size_t DominantAxis() const
Returns the index of the dominant axis.
Definition: Vector-Impl.h:247
T DistanceTo(const E &other) const
Returns the distance to the other vector.
Definition: Vector-Impl.h:289
Point< T, 2 > Ceil(const Point< T, 2 > &a)
Returns element-wise ceiled point.
Definition: Point2-Impl.h:492
const T & operator[](size_t i) const
Returns the const reference to the i -th element.
Definition: Vector-Impl.h:519
Matrix< T, 2, 2 > operator+(const Matrix< T, 2, 2 > &a, const Matrix< T, 2, 2 > &b)
Returns a + b (element-size).
Definition: Matrix2x2-Impl.h:660
T y
Y (or the second) component of the vector.
Definition: Vector4.h:35
size_t SubdominantAxis() const
Returns the index of the subdominant axis.
Definition: Vector-Impl.h:258
VectorTypeCast< U, Vector< T, N >, T > CastTo() const
Returns a vector with different value type.
Definition: Vector-Impl.h:313
T Square(T x)
Returns the square of x.
Definition: MathUtils-Impl.h:111
Vector & operator=(const std::initializer_list< U > &list)
Set vector instance with initializer list.
VectorSub< T, Vector, E > Sub(const E &v) const
Computes this - v.
Generic statically-sized N-D vector class.
Definition: Vector.h:33
Vector()
Constructs a vector with zeros.
Definition: Vector-Impl.h:17
bool IsEqual(const E &other) const
Returns true if other is the same as this vector.
Definition: Vector-Impl.h:320
T w
W (or the fourth) component of the vector.
Definition: Vector4.h:41
T LengthSquared() const
Returns the squared length of the vector.
Definition: Vector-Impl.h:282
T At(size_t i) const
Returns const reference to the i -th element of the vector.
Definition: Vector-Impl.h:164
Point< T, 2 > Floor(const Point< T, 2 > &a)
Returns element-wise floored point.
Definition: Point2-Impl.h:498
VectorDiv< T, Vector, E > Div(const E &v) const
Computes this / v.
Vector RDiv(T v) const
Computes (v, v, v, v) / this.
Definition: Vector4-Impl.h:162
T x
X (or the first) component of the vector.
Definition: Vector3.h:29
bool operator==(const E &v) const
Returns true if other is the same as this vector.
Definition: Vector-Impl.h:608
Matrix< T, 2, 2 > operator/(const Matrix< T, 2, 2 > &a, T b)
Definition: Matrix2x2-Impl.h:720
Definition: pybind11Utils.h:24
T z
Z (or the third) component of the vector.
Definition: Vector4.h:38
void IAdd(const T &s)
Computes this += (s, s, ... , s).
Definition: Vector-Impl.h:453
T Min() const
Returns the minimum element.
Definition: Vector-Impl.h:195
T Clamp(T val, T low, T high)
Returns the clamped value.
Definition: MathUtils-Impl.h:123
Vector & operator-=(const T &s)
Computes this -= (s, s, ... , s)
Definition: Vector-Impl.h:562
void Set(const T &s)
Sets all elements to s.
Definition: Vector-Impl.h:55
T Avg() const
Returns the average of all the elements.
Definition: Vector-Impl.h:189
T Dot(const E &v) const
Computes dot product.
Definition: Vector-Impl.h:412
void IMul(const T &s)
Computes this *= (s, s, ... , s).
Definition: Vector-Impl.h:479
VectorScalarDiv< T, Vector > Normalized() const
Returns normalized vector.
Definition: Vector-Impl.h:269
Matrix< T, 2, 2 > operator-(const Matrix< T, 2, 2 > &a)
Returns a matrix with opposite sign.
Definition: Matrix2x2-Impl.h:654
4-D vector class.
Definition: Vector4.h:26
Vector & operator*=(const T &s)
Computes this *= (s, s, ... , s)
Definition: Vector-Impl.h:577
Point< T, 2 > Max(const Point< T, 2 > &a, const Point< T, 2 > &b)
Returns element-wise max point: (max(a.x, b.x), max(a.y, b.y)).
Definition: Point2-Impl.h:480
Vector Sub(T v) const
Computes this - (v, v, v, v).
Definition: Vector4-Impl.h:108
Vector & operator/=(const T &s)
Computes this /= (s, s, ... , s)
Definition: Vector-Impl.h:592
Vector & operator+=(const T &s)
Computes this += (s, s, ... , s)
Definition: Vector-Impl.h:547
VectorMul< T, Vector, E > Mul(const E &v) const
Computes this * v.
T AbsMax() const
Returns the absolute maximum element.
Definition: Vector-Impl.h:234
T DistanceSquaredTo(const E &other) const
Returns the squared distance to the other vector.
Definition: Vector-Impl.h:296
T Sum() const
Returns the sum of all the elements.
Definition: Vector-Impl.h:176
Vector RSub(T v) const
Computes (v, v, v, v) - this.
Definition: Vector4-Impl.h:150
T Cubic(T x)
Returns the cubic of x.
Definition: MathUtils-Impl.h:117
Vector Mul(T v) const
Computes this * (v, v, v, v).
Definition: Vector4-Impl.h:120
bool IsSimilar(const E &other, T epsilon=std::numeric_limits< T >::epsilon()) const
Returns true if other is similar to this vector.
Definition: Vector-Impl.h:340
T AbsMin() const
Returns the absolute minimum element.
Definition: Vector-Impl.h:221
Vector< T, 3 > operator*(const Quaternion< T > &q, const Vector< T, 3 > &v)
Returns quaternion q * vector v.
Definition: Quaternion-Impl.h:481
T x
X (or the first) component of the vector.
Definition: Vector4.h:29
T MonotonicCatmullRom(const T &f0, const T &f1, const T &f2, const T &f3, T f)
Computes monotonic Catmull-Rom interpolation.
Definition: MathUtils-Impl.h:228
Vector Add(T v) const
Computes this + (v, v, v, v).
Definition: Vector4-Impl.h:96
T AbsMax(T x, T y)
Returns the absolute maximum value among the two inputs.
Definition: MathUtils-Impl.h:45
void ISub(const T &s)
Computes this -= (s, s, ... , s).
Definition: Vector-Impl.h:466
T Sign(T x)
Returns the sign of the value.
Definition: MathUtils-Impl.h:26
VectorAdd< T, Vector, E > Add(const E &v) const
Computes this + v.
bool operator!=(const E &v) const
Returns true if other is the not same as this vector.
Definition: Vector-Impl.h:615
void SetZero()
Sets all elements to zero.
Definition: Vector-Impl.h:98
Point< T, 2 > Min(const Point< T, 2 > &a, const Point< T, 2 > &b)
Returns element-wise min point: (min(a.x, b.x), min(a.y, b.y)).
Definition: Point2-Impl.h:474
VectorScalarRSub< T, Vector > RSub(const T &s) const
Computes (s, s, ... , s) - this.
Definition: Vector-Impl.h:427
T y
Y (or the second) component of the vector.
Definition: Vector3.h:35
T Length() const
Returns the length of the vector.
Definition: Vector-Impl.h:276
void Normalize()
Normalizes this vector.
Definition: Vector-Impl.h:104
void IDiv(const T &s)
Computes this /= (s, s, ... , s).
Definition: Vector-Impl.h:492