Ocular Engine
Vector2.hpp
1 
17 #pragma once
18 #ifndef __H__OCULAR_MATH_VECTOR_2__H__
19 #define __H__OCULAR_MATH_VECTOR_2__H__
20 
21 #include "MathCommon.hpp"
22 #include "Equality.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 Vector2
45  {
46  public:
47 
48  Vector2(T const* values)
49  {
50  x = values[0];
51  y = values[1];
52  }
53 
54  Vector2(T const &pX, T const &pY)
55  {
56  x = pX;
57  y = pY;
58  }
59 
60  Vector2()
61  {
62  x = static_cast<T>(0);
63  y = static_cast<T>(0);
64  }
65 
66  ~Vector2()
67  {
68 
69  }
70 
71  //------------------------------------------------------------------------------
72  // OPERATORS
73  //------------------------------------------------------------------------------
74 
75  T& operator[](unsigned const& index)
76  {
77  switch(index)
78  {
79  case 0:
80  return x;
81 
82  case 1:
83  return y;
84 
85  default:
86  THROW_EXCEPTION("Out-Of-Bounds Vector Access");
87  return x;
88  }
89  }
90 
91  T operator[](unsigned const& index) const
92  {
93  switch(index)
94  {
95  case 0:
96  return x;
97 
98  case 1:
99  return y;
100 
101  default:
102  THROW_EXCEPTION("Out-Of-Bounds Vector Access");
103  return x;
104  }
105  }
106 
107  Vector2<T> operator-()
108  {
109  return Vector2<T>(-x, -y);
110  }
111 
112  Vector2<T>& operator=(Vector2<T> const &rhs)
113  {
114  x = rhs.x;
115  y = rhs.y;
116 
117  return *this;
118  }
119 
120  Vector2<T>& operator+=(Vector2<T> const &rhs)
121  {
122  x += rhs.x;
123  y += rhs.y;
124 
125  return *this;
126  }
127 
128  Vector2<T>& operator+=(T const &rhs)
129  {
130  x += rhs;
131  y += rhs;
132 
133  return *this;
134  }
135 
136  Vector2<T>& operator-=(Vector2<T> const &rhs)
137  {
138  x -= rhs.x;
139  y -= rhs.y;
140 
141  return *this;
142  }
143 
144  Vector2<T>& operator-=(T const &rhs)
145  {
146  x -= rhs;
147  y -= rhs;
148 
149  return *this;
150  }
151 
152  Vector2<T>& operator*=(Vector2<T> const &rhs)
153  {
154  x *= rhs.x;
155  y *= rhs.y;
156 
157  return *this;
158  }
159 
160  Vector2<T>& operator*=(T const &rhs)
161  {
162  x *= rhs;
163  y *= rhs;
164 
165  return *this;
166  }
167 
168  Vector2<T>& operator/=(Vector2<T> const &rhs)
169  {
170  x /= rhs.x;
171  y /= rhs.y;
172 
173  return *this;
174  }
175 
176  Vector2<T>& operator/=(T const &rhs)
177  {
178  x /= rhs;
179  y /= rhs;
180 
181  return *this;
182  }
183 
184  //------------------------------------------------------------------------------
185  // OPERATIONS
186  //------------------------------------------------------------------------------
187 
191  T getMagnitude() const
192  {
193  return std::sqrt((x * x) + (y * y));
194  }
195 
199  T getLength() const
200  {
201  return getMagnitude();
202  }
203 
210  void normalize()
211  {
212  // Normalization is simply multiplying the vector by the reciprocal of its magnitude.
213 
214  double length = getMagnitude();
215 
216  if(IsEqual<T>(length, static_cast<T>(0)))
217  {
218  x = static_cast<T>(0);
219  y = static_cast<T>(0);
220  }
221  else
222  {
223  x /= static_cast<T>(length);
224  y /= static_cast<T>(length);
225  }
226  }
227 
232  {
233  Vector2<T> result(x, y);
234  result.normalize();
235 
236  return result;
237  }
238 
242  T getDeterminant(Vector2<T> const& rhs)
243  {
244  return (x * rhs.y) - (rhs.x * y);
245  }
246 
254  T dot(Vector2<T> const &rhs) const
255  {
256  return (x * rhs.x) + (y * rhs.y);
257  }
258 
266  double angleBetween(Vector2<T> const &rhs) const
267  {
268  Vector2<T> normalLHS = getNormalized();
269  Vector2<T> normalRHS = rhs.getNormalized();
270 
271  double angle = std::acos(normalLHS.dot(normalRHS));
272 
273  if(angle > PI)
274  {
275  angle = PI_TWO - angle;
276  }
277 
278  return angle;
279  }
280 
285  double distanceTo(Vector2<T> const &rhs) const
286  {
287  Vector2<T> distance = (*this) - rhs;
288  return distance.getMagnitude();
289  }
290 
291  //------------------------------------------------------------------------------
292  // VARIABLES
293  //------------------------------------------------------------------------------
294 
295  union { T x, u, s; };
296  union { T y, v, t; };
297 
298  static bool OCULAR_INTERNAL_Force;
299 
300  protected:
301 
302  private:
303  };
304 
305  //----------------------------------------------------------------------------------
306 
307  template<typename T>
308  bool operator==(Vector2<T> const &lhs, Vector2<T> const &rhs)
309  {
310  return IsEqual<T>(lhs.x, rhs.x) && IsEqual<T>(lhs.y, rhs.y);
311  }
312 
313  template<typename T>
314  bool operator!=(Vector2<T> const &lhs, Vector2<T> const &rhs)
315  {
316  return !(lhs == rhs);
317  }
318 
319  template<typename T>
320  Vector2<T> operator+(Vector2<T> const &lhs, Vector2<T> const &rhs)
321  {
322  return Vector2<T>(lhs.x + rhs.x, lhs.y + rhs.y);
323  }
324 
325  template<typename T>
326  Vector2<T> operator+(Vector2<T> const &lhs, T const rhs)
327  {
328  return Vector2<T>(lhs.x + rhs, lhs.y + rhs);
329  }
330 
331  template<typename T>
332  Vector2<T> operator-(Vector2<T> const &lhs, Vector2<T> const &rhs)
333  {
334  return Vector2<T>(lhs.x - rhs.x, lhs.y - rhs.y);
335  }
336 
337  template<typename T>
338  Vector2<T> operator-(Vector2<T> const &lhs, T const &rhs)
339  {
340  return Vector2<T>(lhs.x - rhs, lhs.y - rhs);
341  }
342 
343  template<typename T>
344  Vector2<T> operator*(Vector2<T> const &lhs, Vector2<T> const &rhs)
345  {
346  return Vector2<T>(lhs.x * rhs.x, lhs.y * rhs.y);
347  }
348 
349  template<typename T>
350  Vector2<T> operator*(Vector2<T> const &lhs, T const &rhs)
351  {
352  return Vector2<T>(lhs.x * rhs, lhs.y * rhs);
353  }
354 
355  template<typename T>
356  Vector2<T> operator/(Vector2<T> const &lhs, Vector2<T> const &rhs)
357  {
358  return Vector2<T>(lhs.x / rhs.x, lhs.y / rhs.y);
359  }
360 
361  template<typename T>
362  Vector2<T> operator/(Vector2<T> const &lhs, T const &rhs)
363  {
364  return Vector2<T>(lhs.x / rhs, lhs.y / rhs);
365  }
366 
367  //--------------------------------------------
368  // Common vector formats
369 
370  typedef Vector2<int32_t> Vector2i;
371  typedef Vector2<uint32_t> Vector2ui;
372  typedef Vector2<float> Vector2f;
373  typedef Vector2<double> Vector2d;
374 
375  typedef Vector2f Point2f;
376  typedef Vector2d Point2d;
377 
378  }
382 }
387 OCULAR_REGISTER_TYPE_CUSTOM(Ocular::Math::Vector2i, "Vector2i");
388 OCULAR_REGISTER_TYPE_CUSTOM(Ocular::Math::Vector2ui, "Vector2ui");
389 OCULAR_REGISTER_TYPE_CUSTOM(Ocular::Math::Vector2f, "Vector2f");
390 OCULAR_REGISTER_TYPE_CUSTOM(Ocular::Math::Vector2d, "Vector2d");
391 
392 //------------------------------------------------------------------------------------------
393 
394 #endif
T getLength() const
Definition: Vector2.hpp:199
T getMagnitude() const
Definition: Vector2.hpp:191
void normalize()
Definition: Vector2.hpp:210
double angleBetween(Vector2< T > const &rhs) const
Definition: Vector2.hpp:266
Note: Once this library is made dynamic, this will no longer be needed.
Definition: Common.hpp:70
Definition: Vector2.hpp:44
T dot(Vector2< T > const &rhs) const
Definition: Vector2.hpp:254
double distanceTo(Vector2< T > const &rhs) const
Definition: Vector2.hpp:285
Vector2< T > getNormalized() const
Definition: Vector2.hpp:231