Ocular Engine
Vector4.hpp
1 
17 #pragma once
18 #ifndef __H__OCULAR_MATH_VECTOR_4__H__
19 #define __H__OCULAR_MATH_VECTOR_4__H__
20 
21 #include "Equality.hpp"
22 #include "Vector3.hpp"
23 #include "Utilities/Types.hpp"
24 #include "Exceptions/Exception.hpp"
25 
26 //------------------------------------------------------------------------------------------
27 
32 namespace Ocular
33 {
38  namespace Math
39  {
43  template<typename T>
44  class Vector4
45  {
46  public:
47 
48  Vector4(T const* values)
49  {
50  x = values[0];
51  y = values[1];
52  z = values[2];
53  w = values[3];
54  }
55 
56  Vector4(Vector3<T> const& vec, T pW = static_cast<T>(1.0f))
57  {
58  x = vec.x;
59  y = vec.y;
60  z = vec.z;
61  w = pW;
62  }
63 
64  Vector4(T const &pX, T const &pY, T const &pZ, T const &pW)
65  {
66  x = pX;
67  y = pY;
68  z = pZ;
69  w = pW;
70  }
71 
72  Vector4()
73  {
74  x = static_cast<T>(0.0);
75  y = static_cast<T>(0.0);
76  z = static_cast<T>(0.0);
77  w = static_cast<T>(1.0);
78  }
79 
80  ~Vector4()
81  {
82 
83  }
84 
85  //------------------------------------------------------------------------------
86  // OPERATORS
87  //------------------------------------------------------------------------------
88 
89  T& operator[](unsigned const& index)
90  {
91  switch(index)
92  {
93  case 0:
94  return x;
95 
96  case 1:
97  return y;
98 
99  case 2:
100  return z;
101 
102  case 3:
103  return w;
104 
105  default:
106  THROW_EXCEPTION("Out-Of-Bounds Vector Access");
107  return x;
108  }
109  }
110 
111  T operator[](unsigned const& index) const
112  {
113  switch(index)
114  {
115  case 0:
116  return x;
117 
118  case 1:
119  return y;
120 
121  case 2:
122  return z;
123 
124  case 3:
125  return w;
126 
127  default:
128  THROW_EXCEPTION("Out-Of-Bounds Vector Access");
129  return x;
130  }
131  }
132 
133  Vector4<T> operator-()
134  {
135  return Vector4<T>(-x, -y, -z, -w);
136  }
137 
138  Vector4<T>& operator=(Vector4<T> const &rhs)
139  {
140  x = rhs.x;
141  y = rhs.y;
142  z = rhs.z;
143  w = rhs.w;
144 
145  return *this;
146  }
147 
148  Vector4<T>& operator=(Vector3<T> const &rhs)
149  {
150  x = rhs.x;
151  y = rhs.y;
152  z = rhs.z;
153  w = static_cast<T>(1);
154 
155  return *this;
156  }
157 
158  Vector4<T>& operator+=(Vector4<T> const &rhs)
159  {
160  x += rhs.x;
161  y += rhs.y;
162  z += rhs.z;
163  w += rhs.w;
164 
165  return *this;
166  }
167 
168  Vector4<T>& operator+=(T const &rhs)
169  {
170  x += rhs;
171  y += rhs;
172  z += rhs;
173  w += rhs;
174 
175  return *this;
176  }
177 
178  Vector4<T>& operator-=(Vector4<T> const &rhs)
179  {
180  x -= rhs.x;
181  y -= rhs.y;
182  z -= rhs.z;
183  w -= rhs.w;
184 
185  return *this;
186  }
187 
188  Vector4<T>& operator-=(T const &rhs)
189  {
190  x -= rhs;
191  y -= rhs;
192  z -= rhs;
193  w -= rhs;
194 
195  return *this;
196  }
197 
198  Vector4<T>& operator*=(Vector4<T> const &rhs)
199  {
200  x *= rhs.x;
201  y *= rhs.y;
202  z *= rhs.z;
203  w *= rhs.w;
204 
205  return *this;
206  }
207 
208  Vector4<T>& operator*=(T const &rhs)
209  {
210  x *= rhs;
211  y *= rhs;
212  z *= rhs;
213  w *= rhs;
214 
215  return *this;
216  }
217 
218  Vector4<T>& operator/=(Vector4<T> const &rhs)
219  {
220  x /= rhs.x;
221  y /= rhs.y;
222  z /= rhs.z;
223  w /= rhs.w;
224 
225  return *this;
226  }
227 
228  Vector4<T>& operator/=(T const &rhs)
229  {
230  x /= rhs;
231  y /= rhs;
232  z /= rhs;
233  w /= rhs;
234 
235  return *this;
236  }
237 
238  //------------------------------------------------------------------------------
239  // OPERATIONS
240  //------------------------------------------------------------------------------
241 
245  Vector2<T> xy() const
246  {
247  return Vector2<T>(x, y);
248  }
249 
253  Vector3<T> xyz() const
254  {
255  return Vector3<T>(x, y, z);
256  }
257 
261  T getMagnitude() const
262  {
263  return std::sqrt((x * x) + (y * y) + (z * z) + (w * w));
264  }
265 
269  T getLength() const
270  {
271  return getMagnitude();
272  }
273 
277  void normalize()
278  {
279  // Normalization is simply multiplying the vector by the reciprocal of its magnitude.
280 
281  double length = getMagnitude();
282 
283  if(IsEqual<T>(length, static_cast<T>(0)))
284  {
285  x = static_cast<T>(0);
286  y = static_cast<T>(0);
287  z = static_cast<T>(0);
288  w = static_cast<T>(1);
289  }
290  else
291  {
292  x /= static_cast<T>(length);
293  y /= static_cast<T>(length);
294  z /= static_cast<T>(length);
295  w /= static_cast<T>(length);
296  }
297  }
298 
303  {
304  Vector4<T> result(x, y, z, w);
305  result.normalize();
306 
307  return result;
308  }
309 
317  T dot(Vector4<T> const &rhs) const
318  {
319  return (x * rhs.x) + (y * rhs.y) + (z * rhs.z) + (w * rhs.w);
320  }
321 
329  T angleBetween(Vector4<T> const &rhs) const
330  {
331  Vector4<T> normalLHS = getNormalized();
332  Vector4<T> normalRHS = rhs.getNormalized();
333 
334  double angle = std::acos(normalLHS.dot(normalRHS));
335 
336  if(angle > PI)
337  {
338  angle = PI_TWO - angle;
339  }
340 
341  return static_cast<T>(angle);
342  }
343 
348  T distanceTo(Vector4<T> const &rhs) const
349  {
350  Vector4<T> distance = (*this) - rhs;
351  return distance.getMagnitude();
352  }
353 
357  void homogenize()
358  {
359  x /= w;
360  y /= w;
361  z /= w;
362  w /= w;
363  }
364 
372  static Vector4<T> Midpoint(Vector4<T> const& a, Vector4<T> const& b)
373  {
374  T two = static_cast<T>(2);
375 
376  return Vector4<T>(
377  ((a.x + b.x) / two),
378  ((a.y + b.y) / two),
379  ((a.z + b.z) / two),
380  ((a.w + b.w) / two));
381  }
382 
383  //------------------------------------------------------------------------------
384  // VARIABLES
385  //------------------------------------------------------------------------------
386 
387  union { T x, r, u, s; };
388  union { T y, g, v, t; };
389  union { T z, b, p; };
390  union { T w, a, q; };
391 
392  static bool OCULAR_INTERNAL_Force;
393 
394  protected:
395 
396  private:
397  };
398 
399  //----------------------------------------------------------------------------------
400 
401  template<typename T>
402  bool operator==(Vector4<T> const &lhs, Vector4<T> const &rhs)
403  {
404  return IsEqual<T>(lhs.x, rhs.x) && IsEqual<T>(lhs.y, rhs.y) && IsEqual<T>(lhs.z, rhs.z) && IsEqual<T>(lhs.w, rhs.w);
405  }
406 
407  template<typename T>
408  bool operator!=(Vector4<T> const &lhs, Vector4<T> const &rhs)
409  {
410  return !(lhs == rhs);
411  }
412 
413  template<typename T>
414  Vector4<T> operator+(Vector4<T> const &lhs, Vector4<T> const &rhs)
415  {
416  return Vector4<T>(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w);
417  }
418 
419  template<typename T>
420  Vector4<T> operator+(Vector4<T> const &lhs, T const &rhs)
421  {
422  return Vector4<T>(lhs.x + rhs, lhs.y + rhs, lhs.z + rhs, lhs.w + rhs);
423  }
424 
425  template<typename T>
426  Vector4<T> operator-(Vector4<T> const &lhs, Vector4<T> const &rhs)
427  {
428  return Vector4<T>(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w);
429  }
430 
431  template<typename T>
432  Vector4<T> operator-(Vector4<T> const &lhs, T const &rhs)
433  {
434  return Vector4<T>(lhs.x - rhs, lhs.y - rhs, lhs.z - rhs, lhs.w - rhs);
435  }
436 
437  template<typename T>
438  Vector4<T> operator*(Vector4<T> const &lhs, Vector4<T> const &rhs)
439  {
440  return Vector4<T>(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w);
441  }
442 
443  template<typename T>
444  Vector4<T> operator*(Vector4<T> const &lhs, T const &rhs)
445  {
446  return Vector4<T>(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs);
447  }
448 
449  template<typename T>
450  Vector4<T> operator/(Vector4<T> const &lhs, Vector4<T> const &rhs)
451  {
452  return Vector4<T>(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z, lhs.w / rhs.w);
453  }
454 
455  template<typename T>
456  Vector4<T> operator/(Vector4<T> const &lhs, T const &rhs)
457  {
458  return Vector4<T>(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs);
459  }
460 
461  typedef Vector4<float> Vector4f;
462  typedef Vector4<double> Vector4d;
463 
464  typedef Vector4f Point4f;
465  typedef Vector4d Point4d;
466  }
470 }
475 OCULAR_REGISTER_TYPE_CUSTOM(Ocular::Math::Vector4f, "Vector4f");
476 OCULAR_REGISTER_TYPE_CUSTOM(Ocular::Math::Vector4d, "Vector4d");
477 
478 //------------------------------------------------------------------------------------------
479 
480 #endif
T getMagnitude() const
Definition: Vector4.hpp:261
Definition: Matrix3x3.hpp:39
T dot(Vector4< T > const &rhs) const
Definition: Vector4.hpp:317
Vector4< T > getNormalized() const
Definition: Vector4.hpp:302
T distanceTo(Vector4< T > const &rhs) const
Definition: Vector4.hpp:348
void homogenize()
Definition: Vector4.hpp:357
Note: Once this library is made dynamic, this will no longer be needed.
Definition: Common.hpp:70
void normalize()
Definition: Vector4.hpp:277
T getLength() const
Definition: Vector4.hpp:269
static Vector4< T > Midpoint(Vector4< T > const &a, Vector4< T > const &b)
Definition: Vector4.hpp:372
T angleBetween(Vector4< T > const &rhs) const
Definition: Vector4.hpp:329