TurtleBrains  0.3.5
High quality, portable, C++ framework for rapid 2D game development.
tb_vector.hpp
1 
9 #ifndef TurtleBrains_Vector_hpp
10 #define TurtleBrains_Vector_hpp
11 
12 #include <turtle_brains/math/tb_math.hpp>
13 #include <turtle_brains/math/tb_angle.hpp>
14 #include <turtle_brains/core/tb_error.hpp>
15 #include <turtle_brains/core/tb_defines.hpp> //For tb_unsused
16 
17 namespace TurtleBrains
18 {
19  namespace Math
20  {
21 
30  enum SkipInitialization { kSkipInitialization = 0, };
31 
37  {
42  };
43 
48  class Vector2
49  {
50  public:
54  static Vector2 Zero(void) { return Vector2(0.0f, 0.0f); }
55 
56  union
57  {
58  float mComponents[2];
59 
60 #if defined(tb_visual_cpp)
61 #pragma warning(push)
62 #pragma warning(disable: 4201)
63  struct { float x, y; };
64 #pragma warning(pop)
65 #else
66  struct { float x, y; };
67 #endif
68  };
69 
76  inline explicit Vector2(const SkipInitialization& fastAndStupid)
77  {
78  tb_unused(fastAndStupid);
79  }
80 
84  inline Vector2(void) :
85  x(0.0f),
86  y(0.0f)
87  {
88  }
89 
96  inline Vector2(const float valueX, const float valueY) :
97  x(valueX),
98  y(valueY)
99  {
100  }
101 
107  inline explicit Vector2(const float* componentArray) :
108  x(componentArray[0]),
109  y(componentArray[1])
110  {
111  }
112 
119  inline Vector2(const Vector2& other) :
120  x(other.x),
121  y(other.y)
122  {
123  }
124 
128  inline ~Vector2(void)
129  {
130  }
131 
137  inline Vector2& operator=(const Vector2& other)
138  {
139  x = other.x;
140  y = other.y;
141  return *this;
142  }
143 
153  inline bool operator==(const Vector2& other) const
154  {
155  return (true == IsEqual(x, other.x) && true == IsEqual(y, other.y)) ? true : false;
156  }
157 
162  inline bool operator!=(const Vector2& other) const
163  {
164  return (true == operator==(other)) ? false : true;
165  }
166 
170  inline explicit operator const float*(void) const { return mComponents; }
171 
176  inline explicit operator float*(void) { return mComponents; }
177 
181  inline const float& operator[](const int index) const { return mComponents[index]; }
182 
187  inline float& operator[](const int index) { return mComponents[index]; }
188 
189 #if defined(tb_with_math_operators)
190  inline Vector2 operator+(const Vector2& rightSide) const { return Vector2(x + rightSide.x, y + rightSide.y); }
194 
199  inline Vector2& operator+=(const Vector2& rightSide) { x += rightSide.x; y += rightSide.y; return *this; }
200 
204  inline Vector2 operator-(const Vector2& rightSide) const { return Vector2(x - rightSide.x, y - rightSide.y); }
205 
209  inline Vector2& operator-=(const Vector2& rightSide) { x -= rightSide.x; y -= rightSide.y; return *this; }
210 
214  inline Vector2 operator*(float scalar) const { return Vector2(x * scalar, y * scalar); }
215 
220  friend Vector2 operator*(float scalar, const Vector2& rightSide) { return Vector2(scalar * rightSide.x, scalar * rightSide.y); }
221 
226  inline Vector2& operator*=(float scalar) { x *= scalar; y *= scalar; return *this; }
227 
231  inline Vector2 operator/(float scalar) const { return Vector2(x / scalar, y / scalar); }
232 
237  inline Vector2& operator/=(float scalar) { x /= scalar; y /= scalar; return *this; }
238 
242  friend Vector2 operator/(float scalar, const Vector2& rightSide) { return Vector2(scalar / rightSide.x, scalar / rightSide.y); }
243 
247  inline Vector2 operator-(void) const { return Vector2(-x, -y); }
248 
252  inline float operator*(const Vector2 &rhs) const { return (x * rhs.x) + (y * rhs.y); }
253 
258  inline float Magnitude(void) const { return sqrt((x * x) + (y * y)); }
259 
264  inline float MagnitudeSquared(void) const { return (x * x) + (y * y); }
265 
270  inline Vector2 GetNormalized(void) const
271  {
272  const float magnitude(Magnitude());
273  if (true == IsZero(magnitude)) { return Zero(); }
274  return Vector2(x / magnitude, y / magnitude);
275  }
276 
282  inline float Normalize(void)
283  {
284  const float magnitude(Magnitude());
285  if (false == IsZero(magnitude))
286  {
287  x /= magnitude;
288  y /= magnitude;
289  }
290  return magnitude;
291  }
292 
296  inline void Scale(float scalar) { *this *= scalar; }
297 
305  inline void SetLength(float length) { Normalize(); *this *= length; }
306 #endif /* tb_with_math_operators */
307  };
308 
309 //-------------------------------------------------------------------------------------------------------------------//
310 //-------------------------------------------------------------------------------------------------------------------//
311 //-------------------------------------------------------------------------------------------------------------------//
312 
317  class Vector3
318  {
319  public:
323  static Vector3 Zero(void) { return Vector3(0.0f, 0.0f, 0.0f); }
324 
325  union
326  {
327  float mComponents[3];
328 
329 #if defined(tb_visual_cpp)
330 #pragma warning(push)
331 #pragma warning(disable: 4201)
332  struct { float x, y, z; };
333 #pragma warning(pop)
334 #else
335  struct { float x, y, z; };
336 #endif
337  };
338 
345  inline explicit Vector3(const SkipInitialization& fastAndStupid)
346  {
347  tb_unused(fastAndStupid);
348  }
349 
353  Vector3(void) :
354  x(0.0f),
355  y(0.0f),
356  z(0.0f)
357  {
358  }
359 
367  inline Vector3(const float valueX, const float valueY, const float valueZ) :
368  x(valueX),
369  y(valueY),
370  z(valueZ)
371  {
372  }
373 
380  inline explicit Vector3(const Vector2& other, const float valueZ) :
381  x(other.x),
382  y(other.y),
383  z(valueZ)
384  {
385  }
386 
392  inline explicit Vector3(const float* componentArray) :
393  x(componentArray[0]),
394  y(componentArray[1]),
395  z(componentArray[2])
396  {
397  }
398 
405  Vector3(const Vector3& other) :
406  x(other.x),
407  y(other.y),
408  z(other.z)
409  {
410  }
411 
415  ~Vector3(void)
416  {
417  }
418 
424  inline Vector3& operator=(const Vector3& other)
425  {
426  x = other.x;
427  y = other.y;
428  z = other.z;
429  return *this;
430  }
431 
432  //
433  // TODO: TIM: Planning: Would this be useful to have, or just dangerous?
434  //
435  //inline Vector3& operator=(const Vector2 &v)
436  //{
437  // x = v.x; y = v.y; /* z = z; */
438  // return (*this);
439  //}
440 
450  inline bool operator==(const Vector3& other) const
451  {
452  return (true == IsEqual(x, other.x) && true == IsEqual(y, other.y) && true == IsEqual(z, other.z)) ? true : false;
453  }
454 
459  inline bool operator!=(const Vector3& other) const
460  {
461  return (true == operator==(other)) ? false : true;
462  }
463 
467  inline explicit operator const float*(void) const { return mComponents; }
468 
473  inline explicit operator float*(void) { return mComponents; }
474 
478  inline const float& operator[](const int index) const { return mComponents[index]; }
479 
484  inline float& operator[](const int index) { return mComponents[index]; }
485 
486  #if defined(tb_with_math_operators)
487  inline Vector3 operator+(const Vector3& rightSide) const { return Vector3(x + rightSide.x, y + rightSide.y, z + rightSide.z); }
491 
496  inline Vector3& operator+=(const Vector3& rightSide) { x += rightSide.x; y += rightSide.y; z += rightSide.z; return *this; }
497 
501  inline Vector3 operator-(const Vector3& rightSide) const { return Vector3(x - rightSide.x, y - rightSide.y, z - rightSide.z); }
502 
506  inline Vector3& operator-=(const Vector3& rightSide) { x -= rightSide.x; y -= rightSide.y; z -= rightSide.z; return *this; }
507 
508 
512  inline Vector3 operator*(float scalar) const { return Vector3(x * scalar, y * scalar, z * scalar); }
513 
518  friend Vector3 operator*(float scalar, const Vector3& rightSide) { return Vector3(scalar * rightSide.x, scalar * rightSide.y, scalar * rightSide.z); }
519 
524  inline Vector3& operator*=(float scalar) { x *= scalar; y *= scalar; z *= scalar; return *this; }
525 
529  inline Vector3 operator/(float scalar) const { return Vector3(x / scalar, y / scalar, z / scalar); }
530 
535  inline Vector3& operator/=(float scalar) { x /= scalar; y /= scalar; z /= scalar; return *this; }
536 
540  friend Vector3 operator/(float scalar, const Vector3& rightSide) { return Vector3(scalar / rightSide.x, scalar / rightSide.y, scalar / rightSide.z); }
541 
545  inline Vector3 operator-(void) const { return Vector3(-x, -y, -z); }
546 
550  inline float operator*(const Vector3 &rhs) const { return (x * rhs.x) + (y * rhs.y) + (z * rhs.z); }
551 
556  inline Vector3 operator^(const Vector3& rightSide) const
557  {
558  return Vector3((y * rightSide.z) - (rightSide.y * z), -((x * rightSide.z) - (rightSide.x * z)), (x * rightSide.y) - (rightSide.x * y));
559  }
560 
561 
566  inline float Magnitude(void) const { return sqrt((x * x) + (y * y) + (z * z)); }
567 
572  inline float MagnitudeSquared(void) const { return (x * x) + (y * y) + (z * z); }
573 
578  inline Vector3 GetNormalized(void) const
579  {
580  const float magnitude(Magnitude());
581  if (true == IsZero(magnitude)) { return Zero(); }
582  return Vector3(x / magnitude, y / magnitude, z / magnitude);
583  }
584 
590  inline float Normalize(void)
591  {
592  const float magnitude(Magnitude());
593  if (false == IsZero(magnitude))
594  {
595  x /= magnitude;
596  y /= magnitude;
597  z /= magnitude;
598  }
599  return magnitude;
600  }
601 
605  inline void Scale(float scalar) { *this *= scalar; }
606 
614  inline void SetLength(float length) { Normalize(); *this *= length; }
615  #endif /* tb_with_math_operators */
616  };
617 
618 //-------------------------------------------------------------------------------------------------------------------//
619 //-------------------------------------------------------------------------------------------------------------------//
620 //-------------------------------------------------------------------------------------------------------------------//
621 
626  class Vector4
627  {
628  public:
632  static Vector4 Zero(void) { return Vector4(0.0f, 0.0f, 0.0f, 0.0f); }
633 
634  union
635  {
636  float mComponents[4];
637 
638 #if defined(tb_visual_cpp)
639 #pragma warning(push)
640 #pragma warning(disable: 4201)
641  struct { float x, y, z, w; };
642 #pragma warning(pop)
643 #else
644  struct { float x, y, z, w; };
645 #endif
646  };
647 
654  inline explicit Vector4(const SkipInitialization& fastAndStupid)
655  {
656  tb_unused(fastAndStupid);
657  }
658 
662  inline Vector4(void) :
663  x(0.0f),
664  y(0.0f),
665  z(0.0f),
666  w(0.0f)
667  {
668  }
669 
678  inline Vector4(const float valueX, const float valueY, const float valueZ, const float valueW) :
679  x(valueX),
680  y(valueY),
681  z(valueZ),
682  w(valueW)
683  {
684  }
685 
693  inline explicit Vector4(const Vector2& other, const float valueZ, const float valueW) :
694  x(other.x),
695  y(other.y),
696  z(valueZ),
697  w(valueW)
698  {
699  }
700 
707  inline explicit Vector4(const Vector3& other, const float valueW) :
708  x(other.x),
709  y(other.y),
710  z(other.z),
711  w(valueW)
712  {
713  }
714 
720  inline explicit Vector4(const float* componentArray) :
721  x(componentArray[0]),
722  y(componentArray[1]),
723  z(componentArray[2]),
724  w(componentArray[3])
725  {
726  }
727 
734  inline Vector4(const Vector4& other) :
735  x(other.x),
736  y(other.y),
737  z(other.z),
738  w(other.w)
739  {
740  }
741 
745  ~Vector4(void)
746  {
747  }
748 
754  inline Vector4& operator=(const Vector4& other)
755  {
756  x = other.x;
757  y = other.y;
758  z = other.z;
759  w = other.w;
760  return *this;
761  }
762 
772  inline bool operator==(const Vector4& other) const
773  {
774  return (true == IsEqual(x, other.x) && true == IsEqual(y, other.y) &&
775  true == IsEqual(z, other.z) && true == IsEqual(w, other.w)) ? true : false;
776  }
777 
782  inline bool operator!=(const Vector4& other) const
783  {
784  return (true == operator==(other)) ? false : true;
785  }
786 
790  inline explicit operator const float*(void) const { return mComponents; }
791 
796  inline explicit operator float*(void) { return mComponents; }
797 
801  inline const float& operator[](const int index) const { return mComponents[index]; }
802 
807  inline float& operator[](const int index) { return mComponents[index]; }
808 
809 #if defined(tb_with_math_operators)
810  inline Vector4 operator+(const Vector4& rightSide) const { return Vector4(x + rightSide.x, y + rightSide.y, z + rightSide.z, w + rightSide.w); }
814 
819  inline Vector4& operator+=(const Vector4& rightSide) { x += rightSide.x; y += rightSide.y; z += rightSide.z; w += rightSide.w; return *this; }
820 
824  inline Vector4 operator-(const Vector4& rightSide) const { return Vector4(x - rightSide.x, y - rightSide.y, z - rightSide.z, w - rightSide.w); }
825 
829  inline Vector4& operator-=(const Vector4& rightSide) { x -= rightSide.x; y -= rightSide.y; z -= rightSide.z; w -= rightSide.w; return *this; }
830 
831 
835  inline Vector4 operator*(float scalar) const { return Vector4(x * scalar, y * scalar, z * scalar, w * scalar); }
836 
841  friend Vector4 operator*(float scalar, const Vector4& rightSide) { return Vector4(scalar * rightSide.x, scalar * rightSide.y, scalar * rightSide.z, scalar * rightSide.w); }
842 
847  inline Vector4& operator*=(float scalar) { x *= scalar; y *= scalar; z *= scalar; w *= scalar; return *this; }
848 
852  inline Vector4 operator/(float scalar) const { return Vector4(x / scalar, y / scalar, z / scalar, w / scalar); }
853 
858  inline Vector4& operator/=(float scalar) { x /= scalar; y /= scalar; z /= scalar; w /= scalar; return *this; }
859 
863  friend Vector4 operator/(float scalar, const Vector4& rightSide) { return Vector4(scalar / rightSide.x, scalar / rightSide.y, scalar / rightSide.z, scalar / rightSide.w); }
864 
868  inline Vector4 operator-(void) const { return Vector4(-x, -y, -z, -w); }
869 
873  inline float operator*(const Vector4& rightSide) const { return (x * rightSide.x) + (y * rightSide.y) + (z * rightSide.z) + (w * rightSide.w); }
874 
875  //TODO: TIM: Reconsider: Does this work, and if it does, how do we want to support it? Document if needed.
876  //inline Vector4 operator^(const Vector4 &rhs) const { return Vector4((y * rhs.z) - (rhs.y * z), -((x * rhs.z) - (rhs.x * z)), (x * rhs.y) - (rhs.x * y)); }
877 
882  inline float Magnitude(void) const { return sqrt((x * x) + (y * y) + (z * z) + (w * w)); }
883 
888  inline float MagnitudeSquared(void) const { return (x * x) + (y * y) + (z * z) + (w * w); }
889 
894  inline Vector4 GetNormalized(void) const
895  {
896  const float magnitude(Magnitude());
897  if (true == IsZero(magnitude)) { return Zero(); }
898  return Vector4(x / magnitude, y / magnitude, z / magnitude, w / magnitude);
899  }
900 
906  inline float Normalize(void)
907  {
908  const float magnitude(Magnitude());
909  if (false == IsZero(magnitude))
910  {
911  x /= magnitude;
912  y /= magnitude;
913  z /= magnitude;
914  w /= magnitude;
915  }
916  return magnitude;
917  }
918 
922  inline void Scale(float scalar) { *this *= scalar; }
923 
931  inline void SetLength(float length) { Normalize(); *this *= length; }
932 #endif /* tb_with_math_operators */
933  };
934 
935 //-------------------------------------------------------------------------------------------------------------------//
936 //-------------------------------------------------------------------------------------------------------------------//
937 //-------------------------------------------------------------------------------------------------------------------//
938 
949  inline Vector2* Vector2Add(Vector2* result, const Vector2* leftSide, const Vector2* rightSide)
950  {
951  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
952  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
953  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
954 
955  result->x = leftSide->x + rightSide->x;
956  result->y = leftSide->y + rightSide->y;
957  return result;
958  }
959 
963  inline Vector3* Vector3Add(Vector3* result, const Vector3* leftSide, const Vector3* rightSide)
964  {
965  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
966  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
967  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
968 
969  result->x = leftSide->x + rightSide->x;
970  result->y = leftSide->y + rightSide->y;
971  result->z = leftSide->z + rightSide->z;
972  return result;
973  }
974 
978  inline Vector4* Vector4Add(Vector4* result, const Vector4* leftSide, const Vector4* rightSide)
979  {
980  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
981  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
982  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
983 
984  result->x = leftSide->x + rightSide->x;
985  result->y = leftSide->y + rightSide->y;
986  result->z = leftSide->z + rightSide->z;
987  result->w = leftSide->w + rightSide->w;
988  return result;
989  }
990 
1001  inline Vector2* Vector2Subtract(Vector2* result, const Vector2* leftSide, const Vector2* rightSide)
1002  {
1003  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1004  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1005  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1006 
1007  result->x = leftSide->x - rightSide->x;
1008  result->y = leftSide->y - rightSide->y;
1009  return result;
1010  }
1011 
1015  inline Vector3* Vector3Subtract(Vector3* result, const Vector3* leftSide, const Vector3* rightSide)
1016  {
1017  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1018  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1019  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1020 
1021  result->x = leftSide->x - rightSide->x;
1022  result->y = leftSide->y - rightSide->y;
1023  result->z = leftSide->z - rightSide->z;
1024  return result;
1025  }
1026 
1030  inline Vector4* Vector4Subtract(Vector4* result, const Vector4* leftSide, const Vector4* rightSide)
1031  {
1032  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1033  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1034  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1035 
1036  result->x = leftSide->x - rightSide->x;
1037  result->y = leftSide->y - rightSide->y;
1038  result->z = leftSide->z - rightSide->z;
1039  result->w = leftSide->w - rightSide->w;
1040  return result;
1041  }
1042 
1052  inline Vector2* Vector2Scale(Vector2* result, const Vector2* input, const float scalar)
1053  {
1054  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1055  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1056 
1057  result->x = input->x * scalar;
1058  result->y = input->y * scalar;
1059  return result;
1060  }
1061 
1065  inline Vector3* Vector3Scale(Vector3* result, const Vector3* input, const float scalar)
1066  {
1067  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1068  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1069 
1070  result->x = input->x * scalar;
1071  result->y = input->y * scalar;
1072  result->z = input->z * scalar;
1073  return result;
1074  }
1075 
1079  inline Vector4* Vector4Scale(Vector4* result, const Vector4* input, const float scalar)
1080  {
1081  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1082  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1083 
1084  result->x = input->x * scalar;
1085  result->y = input->y * scalar;
1086  result->z = input->z * scalar;
1087  result->w = input->w * scalar;
1088  return result;
1089  }
1090 
1100  inline Vector2* Vector2ScaleDivide(Vector2* result, const Vector2* input, const float scalar)
1101  {
1102  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1103  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1104 
1105  result->x = input->x / scalar;
1106  result->y = input->y / scalar;
1107  return result;
1108  }
1109 
1113  inline Vector3* Vector3ScaleDivide(Vector3* result, const Vector3* input, const float scalar)
1114  {
1115  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1116  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1117 
1118  result->x = input->x / scalar;
1119  result->y = input->y / scalar;
1120  result->z = input->z / scalar;
1121  return result;
1122  }
1123 
1127  inline Vector4* Vector4ScaleDivide(Vector4* result, const Vector4* input, const float scalar)
1128  {
1129  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1130  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1131 
1132  result->x = input->x / scalar;
1133  result->y = input->y / scalar;
1134  result->z = input->z / scalar;
1135  result->w = input->w / scalar;
1136  return result;
1137  }
1138 
1147  inline Vector2* Vector2Negate(Vector2* result, const Vector2* input)
1148  {
1149  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1150  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1151 
1152  result->x = -input->x;
1153  result->y = -input->y;
1154  return result;
1155  }
1156 
1160  inline Vector3* Vector3Negate(Vector3* result, const Vector3* input)
1161  {
1162  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1163  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1164 
1165  result->x = -input->x;
1166  result->y = -input->y;
1167  result->z = -input->z;
1168  return result;
1169  }
1170 
1174  inline Vector4* Vector4Negate(Vector4* result, const Vector4* input)
1175  {
1176  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1177  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1178 
1179  result->x = -input->x;
1180  result->y = -input->y;
1181  result->z = -input->z;
1182  result->w = -input->w;
1183  return result;
1184  }
1185 
1194  inline float Vector2DotProduct(const Vector2* leftSide, const Vector2* rightSide)
1195  {
1196  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1197  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1198  return (leftSide->x * rightSide->x) + (leftSide->y * rightSide->y);
1199  }
1200 
1204  inline float Vector3DotProduct(const Vector3* leftSide, const Vector3* rightSide)
1205  {
1206  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1207  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1208  return (leftSide->x * rightSide->x) + (leftSide->y * rightSide->y) + (leftSide->z * rightSide->z);
1209  }
1210 
1214  inline float Vector4DotProduct(const Vector4* leftSide, const Vector4* rightSide)
1215  {
1216  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1217  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1218  return (leftSide->x * rightSide->x) + (leftSide->y * rightSide->y) + (leftSide->z * rightSide->z) + (leftSide->w * rightSide->w);
1219  }
1220 
1234  inline Vector3* Vector3CrossProduct(Vector3* result, const Vector3* leftSide, const Vector3* rightSide)
1235  {
1236  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1237  tb_error_if(nullptr == leftSide, "tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
1238  tb_error_if(nullptr == rightSide, "tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
1239  tb_error_if(leftSide == rightSide, "tbExternalError: Invalid parameter; expected leftSide to be different from rightSide.");
1240  tb_error_if(result == leftSide || result == rightSide, "Invalid parameter; expected result to be different than leftSide and rightSide");
1241 
1242  result->x = ((leftSide->y * rightSide->z) - (rightSide->y * leftSide->z));
1243  result->y = -(((leftSide->x * rightSide->z) - (rightSide->x * leftSide->z)));
1244  result->z = ((leftSide->x * rightSide->y) - (rightSide->x * leftSide->y));
1245  return result;
1246  }
1247 
1255  inline float Vector2Magnitude(const Vector2* input)
1256  {
1257  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1258  return sqrt((input->x * input->x) + (input->y * input->y));
1259  }
1260 
1264  inline float Vector3Magnitude(const Vector3* input)
1265  {
1266  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1267  return sqrt((input->x * input->x) + (input->y * input->y) + (input->z * input->z));
1268  }
1269 
1273  inline float Vector4Magnitude(const Vector4* input)
1274  {
1275  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1276  return sqrt((input->x * input->x) + (input->y * input->y) + (input->z * input->z) + (input->w * input->w));
1277  }
1278 
1287  inline float Vector2MagnitudeSquared(const Vector2* input)
1288  {
1289  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1290  return (input->x * input->x) + (input->y * input->y);
1291  }
1292 
1296  inline float Vector3MagnitudeSquared(const Vector3* input)
1297  {
1298  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1299  return (input->x * input->x) + (input->y * input->y) + (input->z * input->z);
1300  }
1301 
1305  inline float Vector4MagnitudeSquared(const Vector4* input)
1306  {
1307  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1308  return (input->x * input->x) + (input->y * input->y) + (input->z * input->z) + (input->w * input->w);
1309  }
1310 
1319  inline Vector2* Vector2Normalize(Vector2* result, const Vector2* input)
1320  {
1321  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1322  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1323 
1324  const float magnitude = Vector2Magnitude(input);
1325  if (true == IsZero(magnitude))
1326  {
1327  result->x = 0.0f;
1328  result->y = 0.0f;
1329  }
1330  else
1331  {
1332  result->x = input->x / magnitude;
1333  result->y = input->y / magnitude;
1334  }
1335  return result;
1336  }
1337 
1341  inline Vector3* Vector3Normalize(Vector3* result, const Vector3* input)
1342  {
1343  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1344  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1345 
1346  const float magnitude = Vector3Magnitude(input);
1347  if (true == IsZero(magnitude))
1348  {
1349  result->x = 0.0f;
1350  result->y = 0.0f;
1351  result->z = 0.0f;
1352  }
1353  else
1354  {
1355  result->x = input->x / magnitude;
1356  result->y = input->y / magnitude;
1357  result->z = input->z / magnitude;
1358  }
1359  return result;
1360  }
1361 
1365  inline Vector4* Vector4Normalize(Vector4* result, const Vector4* input)
1366  {
1367  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1368  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1369 
1370  const float magnitude = Vector4Magnitude(input);
1371  if (true == IsZero(magnitude))
1372  {
1373  result->x = 0.0f;
1374  result->y = 0.0f;
1375  result->z = 0.0f;
1376  result->w = 0.0f;
1377  }
1378  else
1379  {
1380  result->x = input->x / magnitude;
1381  result->y = input->y / magnitude;
1382  result->z = input->z / magnitude;
1383  result->w = input->w / magnitude;
1384  }
1385  return result;
1386  }
1387 
1398  inline Vector2* Vector2NormalizeMagnitude(Vector2* result, const Vector2* input, float& magnitude)
1399  {
1400  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1401  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1402 
1403  magnitude = Vector2Magnitude(input);
1404  if (true == IsZero(magnitude))
1405  {
1406  result->x = 0.0f;
1407  result->y = 0.0f;
1408  }
1409  else
1410  {
1411  result->x = input->x / magnitude;
1412  result->y = input->y / magnitude;
1413  }
1414  return result;
1415  }
1416 
1420  inline Vector3* Vector3NormalizeMagnitude(Vector3* result, const Vector3* input, float &magnitude)
1421  {
1422  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1423  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1424 
1425  magnitude = Vector3Magnitude(input);
1426  if (true == IsZero(magnitude))
1427  {
1428  result->x = 0.0f;
1429  result->y = 0.0f;
1430  result->z = 0.0f;
1431  }
1432  else
1433  {
1434  result->x = input->x / magnitude;
1435  result->y = input->y / magnitude;
1436  result->z = input->z / magnitude;
1437  }
1438  return result;
1439  }
1440 
1444  inline Vector4* Vector4NormalizeMagnitude(Vector4* result, const Vector4* input, float &magnitude)
1445  {
1446  tb_error_if(nullptr == result, "tbExternalError: Invalid parameter for result, expected valid pointer.");
1447  tb_error_if(nullptr == input, "tbExternalError: Invalid parameter for input, expected valid pointer.");
1448 
1449  magnitude = Vector4Magnitude(input);
1450  if (true == IsZero(magnitude))
1451  {
1452  result->x = 0.0f;
1453  result->y = 0.0f;
1454  result->z = 0.0f;
1455  result->w = 0.0f;
1456  }
1457  else
1458  {
1459  result->x = input->x / magnitude;
1460  result->y = input->y / magnitude;
1461  result->z = input->z / magnitude;
1462  result->w = input->w / magnitude;
1463  }
1464  return result;
1465  }
1466 
1471  inline Angle Vector3AngleBetween(const Vector3* left, const Vector3* right)
1472  {
1473  const float productOfMagnitudes(Vector3Magnitude(left) * Vector3Magnitude(right));
1474  if (true == IsZero(productOfMagnitudes)) { return 0.0_radians; }
1475  const float value(Vector3DotProduct(left, right) / productOfMagnitudes);
1476  const float clampedValue((value < -1.0f) ? -1.0f : (value > 1.0f) ? 1.0f : value); //Clamp: -1.0f <= value <= 1.0f
1477  return Angle::Radians(acos(clampedValue));
1478  }
1479 
1484  static inline Vector3& RotationXZToForwardVector3(Vector3& result, const Angle& orientation)
1485  {
1486  result.x = sin(orientation.AsRadians());
1487  result.y = 0.0f;
1488  result.z = -cos(orientation.AsRadians());
1489  return result;
1490  }
1491 
1496  static inline Vector2& RotationToForwardVector2(Vector2& result, const Angle& orientation)
1497  {
1498  result.x = sin(orientation.AsRadians());
1499  result.y = -cos(orientation.AsRadians());
1500  return result;
1501  }
1502 
1510  static inline Angle ForwardVector3ToRotationXZ(const Vector3& forward)
1511  {
1512  Vector3 vZAxis(0.0f, 0.0f, -1.0f);
1513  float orientation = acos((vZAxis.x * forward.x) + (vZAxis.y * forward.y) + (vZAxis.z * forward.z));
1514  if (forward.x < 0.0f)
1515  {
1516  orientation = fabs(orientation - kTwoPi);
1517  }
1518  return Angle::Radians(orientation);
1519  }
1520 
1528  static inline Angle ForwardVector2ToRotation(const Vector2& forward)
1529  {
1530  Vector2 yAxis(0.0f, -1.0f);
1531  float orientation = acos((yAxis.x * forward.x) + (yAxis.y * forward.y));
1532  if (forward.x < 0.0f)
1533  {
1534  orientation = fabs(orientation - kTwoPi);
1535  }
1536  return Angle::Radians(orientation);
1537  }
1538 
1539  }; /* namespace Math */
1540 }; /* namespace TurtleBrains */
1541 
1542 namespace tbMath = TurtleBrains::Math;
1543 
1544 #endif /* TurtleBrains_Vector_hpp */
Vector2 * Vector2NormalizeMagnitude(Vector2 *result, const Vector2 *input, float &magnitude)
Definition: tb_vector.hpp:1398
Definition: tb_vector.hpp:48
Vector4(const Vector2 &other, const float valueZ, const float valueW)
Definition: tb_vector.hpp:693
Vector4 * Vector4Negate(Vector4 *result, const Vector4 *input)
Definition: tb_vector.hpp:1174
Vector4(const float valueX, const float valueY, const float valueZ, const float valueW)
Definition: tb_vector.hpp:678
Type AsRadians(void) const
Definition: tb_angle.hpp:79
Vector3(const SkipInitialization &fastAndStupid)
Definition: tb_vector.hpp:345
bool operator!=(const Vector2 &other) const
Definition: tb_vector.hpp:162
Angle Vector3AngleBetween(const Vector3 *left, const Vector3 *right)
Definition: tb_vector.hpp:1471
Vector4(const SkipInitialization &fastAndStupid)
Definition: tb_vector.hpp:654
Contains objects and functions for dealing with Vector and Matrix math.
float Vector4DotProduct(const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.hpp:1214
Vector3 & operator=(const Vector3 &other)
Definition: tb_vector.hpp:424
bool operator==(const Vector3 &other) const
Definition: tb_vector.hpp:450
float & operator[](const int index)
Definition: tb_vector.hpp:807
Vector4(const Vector3 &other, const float valueW)
Definition: tb_vector.hpp:707
Vector4(const Vector4 &other)
Definition: tb_vector.hpp:734
const float & operator[](const int index) const
Definition: tb_vector.hpp:801
Vector4(const float *componentArray)
Definition: tb_vector.hpp:720
float Vector4MagnitudeSquared(const Vector4 *input)
Definition: tb_vector.hpp:1305
Vector2(void)
Definition: tb_vector.hpp:84
Definition: tb_vector.hpp:40
Definition: tb_vector.hpp:317
static Vector2 & RotationToForwardVector2(Vector2 &result, const Angle &orientation)
Definition: tb_vector.hpp:1496
Vector3(const Vector2 &other, const float valueZ)
Definition: tb_vector.hpp:380
bool IsZero(const Type &value)
Definition: tb_math.hpp:53
Vector4 * Vector4Add(Vector4 *result, const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.hpp:978
Vector4 * Vector4Subtract(Vector4 *result, const Vector4 *leftSide, const Vector4 *rightSide)
Definition: tb_vector.hpp:1030
bool operator==(const Vector2 &other) const
Definition: tb_vector.hpp:153
Vector2 * Vector2Subtract(Vector2 *result, const Vector2 *leftSide, const Vector2 *rightSide)
Definition: tb_vector.hpp:1001
Here is some information about the primary namespace.
Definition: tb_application_dialog.hpp:21
Vector3(void)
Definition: tb_vector.hpp:353
Vector3 * Vector3Add(Vector3 *result, const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.hpp:963
static Vector2 Zero(void)
Definition: tb_vector.hpp:54
Vector3 * Vector3Scale(Vector3 *result, const Vector3 *input, const float scalar)
Definition: tb_vector.hpp:1065
#define tb_unused(parameter)
Definition: tb_defines.hpp:25
float Vector4Magnitude(const Vector4 *input)
Definition: tb_vector.hpp:1273
Vector3 * Vector3Normalize(Vector3 *result, const Vector3 *input)
Definition: tb_vector.hpp:1341
Definition: tb_vector.hpp:41
VectorComponent
Definition: tb_vector.hpp:36
SkipInitialization
Definition: tb_vector.hpp:30
Vector3 * Vector3NormalizeMagnitude(Vector3 *result, const Vector3 *input, float &magnitude)
Definition: tb_vector.hpp:1420
bool IsEqual(const Type &leftValue, const Type &rightValue)
Definition: tb_math.hpp:30
static Angle ForwardVector3ToRotationXZ(const Vector3 &forward)
Definition: tb_vector.hpp:1510
bool operator!=(const Vector3 &other) const
Definition: tb_vector.hpp:459
float Vector2Magnitude(const Vector2 *input)
Definition: tb_vector.hpp:1255
Vector2 * Vector2Negate(Vector2 *result, const Vector2 *input)
Definition: tb_vector.hpp:1147
static AngleType Radians(const Type angleInRadians)
Definition: tb_angle.hpp:48
Vector4 * Vector4NormalizeMagnitude(Vector4 *result, const Vector4 *input, float &magnitude)
Definition: tb_vector.hpp:1444
Vector4 & operator=(const Vector4 &other)
Definition: tb_vector.hpp:754
Vector2 & operator=(const Vector2 &other)
Definition: tb_vector.hpp:137
static Vector3 & RotationXZToForwardVector3(Vector3 &result, const Angle &orientation)
Definition: tb_vector.hpp:1484
static Vector4 Zero(void)
Definition: tb_vector.hpp:632
Vector4 * Vector4Scale(Vector4 *result, const Vector4 *input, const float scalar)
Definition: tb_vector.hpp:1079
Vector4 * Vector4Normalize(Vector4 *result, const Vector4 *input)
Definition: tb_vector.hpp:1365
Vector3 * Vector3Subtract(Vector3 *result, const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.hpp:1015
Vector2 * Vector2Add(Vector2 *result, const Vector2 *leftSide, const Vector2 *rightSide)
Definition: tb_vector.hpp:949
bool operator!=(const Vector4 &other) const
Definition: tb_vector.hpp:782
~Vector4(void)
Definition: tb_vector.hpp:745
Vector2 * Vector2Normalize(Vector2 *result, const Vector2 *input)
Definition: tb_vector.hpp:1319
~Vector3(void)
Definition: tb_vector.hpp:415
float Vector2MagnitudeSquared(const Vector2 *input)
Definition: tb_vector.hpp:1287
float Vector3DotProduct(const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.hpp:1204
Vector2(const SkipInitialization &fastAndStupid)
Definition: tb_vector.hpp:76
Vector3 * Vector3ScaleDivide(Vector3 *result, const Vector3 *input, const float scalar)
Definition: tb_vector.hpp:1113
Vector2(const Vector2 &other)
Definition: tb_vector.hpp:119
float & operator[](const int index)
Definition: tb_vector.hpp:187
Vector2(const float valueX, const float valueY)
Definition: tb_vector.hpp:96
Vector2 * Vector2ScaleDivide(Vector2 *result, const Vector2 *input, const float scalar)
Definition: tb_vector.hpp:1100
Vector3(const float valueX, const float valueY, const float valueZ)
Definition: tb_vector.hpp:367
Vector3 * Vector3CrossProduct(Vector3 *result, const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.hpp:1234
Vector3(const float *componentArray)
Definition: tb_vector.hpp:392
float Vector2DotProduct(const Vector2 *leftSide, const Vector2 *rightSide)
Definition: tb_vector.hpp:1194
Vector4 * Vector4ScaleDivide(Vector4 *result, const Vector4 *input, const float scalar)
Definition: tb_vector.hpp:1127
Definition: tb_vector.hpp:39
Definition: tb_angle.hpp:34
bool operator==(const Vector4 &other) const
Definition: tb_vector.hpp:772
float & operator[](const int index)
Definition: tb_vector.hpp:484
~Vector2(void)
Definition: tb_vector.hpp:128
Vector4(void)
Definition: tb_vector.hpp:662
float Vector3MagnitudeSquared(const Vector3 *input)
Definition: tb_vector.hpp:1296
Vector2(const float *componentArray)
Definition: tb_vector.hpp:107
Definition: tb_vector.hpp:38
Vector3(const Vector3 &other)
Definition: tb_vector.hpp:405
const float & operator[](const int index) const
Definition: tb_vector.hpp:478
static const float kTwoPi
A constant for Pi * 2 stored in a float.
Definition: tb_constants.hpp:20
static Angle ForwardVector2ToRotation(const Vector2 &forward)
Definition: tb_vector.hpp:1528
#define tb_error_if(errorTest, message,...)
Definition: tb_error.hpp:42
static Vector3 Zero(void)
Definition: tb_vector.hpp:323
const float & operator[](const int index) const
Definition: tb_vector.hpp:181
Vector3 * Vector3Negate(Vector3 *result, const Vector3 *input)
Definition: tb_vector.hpp:1160
float Vector3Magnitude(const Vector3 *input)
Definition: tb_vector.hpp:1264
Definition: tb_vector.hpp:626
Vector2 * Vector2Scale(Vector2 *result, const Vector2 *input, const float scalar)
Definition: tb_vector.hpp:1052