vector3.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. // Copyright 2010 Michael Smith, all rights reserved.
  14. // Derived closely from:
  15. /****************************************
  16. * 3D Vector Classes
  17. * By Bill Perone (billperone@yahoo.com)
  18. * Original: 9-16-2002
  19. * Revised: 19-11-2003
  20. * 11-12-2003
  21. * 18-12-2003
  22. * 06-06-2004
  23. *
  24. * Copyright 2003, This code is provided "as is" and you can use it freely as long as
  25. * credit is given to Bill Perone in the application it is used in
  26. *
  27. * Notes:
  28. * if a*b = 0 then a & b are orthogonal
  29. * a%b = -b%a
  30. * a*(b%c) = (a%b)*c
  31. * a%b = a(cast to matrix)*b
  32. * (a%b).length() = area of parallelogram formed by a & b
  33. * (a%b).length() = a.length()*b.length() * sin(angle between a & b)
  34. * (a%b).length() = 0 if angle between a & b = 0 or a.length() = 0 or b.length() = 0
  35. * a * (b%c) = volume of parallelpiped formed by a, b, c
  36. * vector triple product: a%(b%c) = b*(a*c) - c*(a*b)
  37. * scalar triple product: a*(b%c) = c*(a%b) = b*(c%a)
  38. * vector quadruple product: (a%b)*(c%d) = (a*c)*(b*d) - (a*d)*(b*c)
  39. * if a is unit vector along b then a%b = -b%a = -b(cast to matrix)*a = 0
  40. * vectors a1...an are linearly dependent if there exists a vector of scalars (b) where a1*b1 + ... + an*bn = 0
  41. * or if the matrix (A) * b = 0
  42. *
  43. ****************************************/
  44. #pragma once
  45. #include <cmath>
  46. #include <float.h>
  47. #include <string.h>
  48. #if MATH_CHECK_INDEXES
  49. #include <assert.h>
  50. #endif
  51. #include "rotations.h"
  52. template <typename T>
  53. class Matrix3;
  54. template <typename T>
  55. class Vector3
  56. {
  57. public:
  58. T x, y, z;
  59. // trivial ctor
  60. constexpr Vector3<T>()
  61. : x(0)
  62. , y(0)
  63. , z(0) {}
  64. // setting ctor
  65. constexpr Vector3<T>(const T x0, const T y0, const T z0)
  66. : x(x0)
  67. , y(y0)
  68. , z(z0) {}
  69. // function call operator
  70. void operator ()(const T x0, const T y0, const T z0)
  71. {
  72. x= x0; y= y0; z= z0;
  73. }
  74. // test for equality
  75. bool operator ==(const Vector3<T> &v) const;
  76. // test for inequality
  77. bool operator !=(const Vector3<T> &v) const;
  78. // negation
  79. Vector3<T> operator -(void) const;
  80. // addition
  81. Vector3<T> operator +(const Vector3<T> &v) const;
  82. // subtraction
  83. Vector3<T> operator -(const Vector3<T> &v) const;
  84. // uniform scaling
  85. Vector3<T> operator *(const T num) const;
  86. // uniform scaling
  87. Vector3<T> operator /(const T num) const;
  88. // addition
  89. Vector3<T> &operator +=(const Vector3<T> &v);
  90. // subtraction
  91. Vector3<T> &operator -=(const Vector3<T> &v);
  92. // uniform scaling
  93. Vector3<T> &operator *=(const T num);
  94. // uniform scaling
  95. Vector3<T> &operator /=(const T num);
  96. // non-uniform scaling
  97. Vector3<T> &operator *=(const Vector3<T> &v) {
  98. x *= v.x; y *= v.y; z *= v.z;
  99. return *this;
  100. }
  101. // allow a vector3 to be used as an array, 0 indexed
  102. T & operator[](uint8_t i) {
  103. T *_v = &x;
  104. #if MATH_CHECK_INDEXES
  105. assert(i >= 0 && i < 3);
  106. #endif
  107. return _v[i];
  108. }
  109. const T & operator[](uint8_t i) const {
  110. const T *_v = &x;
  111. #if MATH_CHECK_INDEXES
  112. assert(i >= 0 && i < 3);
  113. #endif
  114. return _v[i];
  115. }
  116. // dot product
  117. T operator *(const Vector3<T> &v) const;
  118. // multiply a row vector by a matrix, to give a row vector
  119. Vector3<T> operator *(const Matrix3<T> &m) const;
  120. // multiply a column vector by a row vector, returning a 3x3 matrix
  121. Matrix3<T> mul_rowcol(const Vector3<T> &v) const;
  122. // cross product
  123. Vector3<T> operator %(const Vector3<T> &v) const;
  124. // computes the angle between this vector and another vector
  125. float angle(const Vector3<T> &v2) const;
  126. // check if any elements are NAN
  127. bool is_nan(void) const WARN_IF_UNUSED;
  128. // check if any elements are infinity
  129. bool is_inf(void) const WARN_IF_UNUSED;
  130. // check if all elements are zero
  131. bool is_zero(void) const WARN_IF_UNUSED {
  132. return (fabsf(x) < FLT_EPSILON) &&
  133. (fabsf(y) < FLT_EPSILON) &&
  134. (fabsf(z) < FLT_EPSILON);
  135. }
  136. // rotate by a standard rotation
  137. void rotate(enum Rotation rotation);
  138. void rotate_inverse(enum Rotation rotation);
  139. // gets the length of this vector squared
  140. T length_squared() const
  141. {
  142. return (T)(*this * *this);
  143. }
  144. // gets the length of this vector
  145. float length(void) const;
  146. // normalizes this vector
  147. void normalize()
  148. {
  149. *this /= length();
  150. }
  151. // zero the vector
  152. void zero()
  153. {
  154. x = y = z = 0;
  155. }
  156. // returns the normalized version of this vector
  157. Vector3<T> normalized() const
  158. {
  159. return *this/length();
  160. }
  161. // reflects this vector about n
  162. void reflect(const Vector3<T> &n)
  163. {
  164. Vector3<T> orig(*this);
  165. project(n);
  166. *this = *this*2 - orig;
  167. }
  168. // projects this vector onto v
  169. void project(const Vector3<T> &v)
  170. {
  171. *this= v * (*this * v)/(v*v);
  172. }
  173. // returns this vector projected onto v
  174. Vector3<T> projected(const Vector3<T> &v) const
  175. {
  176. return v * (*this * v)/(v*v);
  177. }
  178. // distance from the tip of this vector to another vector squared (so as to avoid the sqrt calculation)
  179. float distance_squared(const Vector3<T> &v) const {
  180. const float dist_x = x-v.x;
  181. const float dist_y = y-v.y;
  182. const float dist_z = z-v.z;
  183. return (dist_x*dist_x + dist_y*dist_y + dist_z*dist_z);
  184. }
  185. // distance from the tip of this vector to a line segment specified by two vectors
  186. float distance_to_segment(const Vector3<T> &seg_start, const Vector3<T> &seg_end) const;
  187. // given a position p1 and a velocity v1 produce a vector
  188. // perpendicular to v1 maximising distance from p1. If p1 is the
  189. // zero vector the return from the function will always be the
  190. // zero vector - that should be checked for.
  191. static Vector3<T> perpendicular(const Vector3<T> &p1, const Vector3<T> &v1)
  192. {
  193. const T d = p1 * v1;
  194. if (fabsf(d) < FLT_EPSILON) {
  195. return p1;
  196. }
  197. const Vector3<T> parallel = (v1 * d) / v1.length_squared();
  198. Vector3<T> perpendicular = p1 - parallel;
  199. return perpendicular;
  200. }
  201. };
  202. typedef Vector3<int16_t> Vector3i;
  203. typedef Vector3<uint16_t> Vector3ui;
  204. typedef Vector3<int32_t> Vector3l;
  205. typedef Vector3<uint32_t> Vector3ul;
  206. typedef Vector3<float> Vector3f;
  207. typedef Vector3<double> Vector3d;