Pioneer
vector3.h
Go to the documentation of this file.
1 // Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #ifndef _VECTOR3_H
5 #define _VECTOR3_H
6 
7 #include "FloatComparison.h"
8 #include "vector2.h"
9 #include <math.h>
10 #include <stdio.h>
11 
12 // Need this pragma due to operator[] implementation.
13 // #pragma pack(4)
14 
15 template <typename T>
16 class vector3 {
17 public:
18  T x, y, z;
19 
20  // Constructor definitions are outside class declaration to enforce that
21  // only float and double versions are possible.
22  vector3() = default;
23  vector3(const vector2f &v, T t);
24  explicit vector3(const T vals[3]);
25  explicit vector3(T val);
26  vector3(T _x, T _y, T _z);
27 
28  // disallow implicit conversion between floating point sizes
29  explicit vector3(const vector3<typename other_floating_type<T>::type> &v);
30  explicit vector3(const typename other_floating_type<T>::type vals[3]);
31 
32  const T &operator[](const size_t i) const { return (const_cast<const T *>(&x))[i]; }
33  T &operator[](const size_t i) { return (&x)[i]; }
34 
35  vector3 operator+(const vector3 &a) const { return vector3(a.x + x, a.y + y, a.z + z); }
37  {
38  x += a.x;
39  y += a.y;
40  z += a.z;
41  return *this;
42  }
44  {
45  x -= a.x;
46  y -= a.y;
47  z -= a.z;
48  return *this;
49  }
50  vector3 &operator*=(const float a)
51  {
52  x *= a;
53  y *= a;
54  z *= a;
55  return *this;
56  }
57  vector3 &operator*=(const double a)
58  {
59  x *= a;
60  y *= a;
61  z *= a;
62  return *this;
63  }
64  vector3 &operator/=(const float a)
65  {
66  const T inva = T(1.0 / a);
67  x *= inva;
68  y *= inva;
69  z *= inva;
70  return *this;
71  }
72  vector3 &operator/=(const double a)
73  {
74  const T inva = T(1.0 / a);
75  x *= inva;
76  y *= inva;
77  z *= inva;
78  return *this;
79  }
80  vector3 operator-(const vector3 &a) const { return vector3(x - a.x, y - a.y, z - a.z); }
81  vector3 operator-() const { return vector3(-x, -y, -z); }
82 
83  bool operator==(const vector3 &a) const
84  {
85  return is_equal_exact(a.x, x) && is_equal_exact(a.y, y) && is_equal_exact(a.z, z);
86  }
87  bool ExactlyEqual(const vector3 &a) const
88  {
89  return is_equal_exact(a.x, x) && is_equal_exact(a.y, y) && is_equal_exact(a.z, z);
90  }
91 
92  friend vector3 operator+(const vector3 &a, const T &scalar) { return vector3(a.x + scalar, a.y + scalar, a.z + scalar); }
93  friend vector3 operator+(const T scalar, const vector3 &a) { return a + scalar; }
94  friend vector3 operator-(const vector3 &a, const T &scalar) { return vector3(a.x - scalar, a.y - scalar, a.z - scalar); }
95  friend vector3 operator-(const T scalar, const vector3 &a) { return a - scalar; }
96 
97  friend vector3 operator*(const vector3 &a, const vector3 &b) { return vector3(T(a.x * b.x), T(a.y * b.y), T(a.z * b.z)); }
98  friend vector3 operator*(const vector3 &a, const T scalar) { return vector3(T(a.x * scalar), T(a.y * scalar), T(a.z * scalar)); }
99  //friend vector3 operator*(const vector3 &a, const double scalar) { return vector3(T(a.x*scalar), T(a.y*scalar), T(a.z*scalar)); }
100  friend vector3 operator*(const T scalar, const vector3 &a) { return a * scalar; }
101  //friend vector3 operator*(const double scalar, const vector3 &a) { return a*scalar; }
102  friend vector3 operator/(const vector3 &a, const float scalar)
103  {
104  const T inv = 1.0 / scalar;
105  return vector3(a.x * inv, a.y * inv, a.z * inv);
106  }
107  friend vector3 operator/(const vector3 &a, const double scalar)
108  {
109  const T inv = 1.0 / scalar;
110  return vector3(a.x * inv, a.y * inv, a.z * inv);
111  }
112 
113  vector3 Cross(const vector3 &b) const { return vector3(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); }
114  T Dot(const vector3 &b) const { return x * b.x + y * b.y + z * b.z; }
115  T Length() const { return sqrt(x * x + y * y + z * z); }
116  T LengthSqr() const { return x * x + y * y + z * z; }
117  vector3 Lerp(const vector3 &b, const double percent) const
118  {
119  return *this + percent * (b - *this);
120  }
122  {
123  const T l = 1.0f / sqrt(x * x + y * y + z * z);
124  return vector3(x * l, y * l, z * l);
125  }
127  {
128  const T lenSqr = x * x + y * y + z * z;
129  if (lenSqr < 1e-18) // sqrt(lenSqr) < 1e-9
130  return vector3(1, 0, 0);
131  else {
132  const T l = sqrt(lenSqr);
133  return vector3(x / l, y / l, z / l);
134  }
135  }
136 
137  void Print() const { printf("v(%f,%f,%f)\n", x, y, z); }
138 
139  /* Rotate this vector about point o, in axis defined by v. */
140  void ArbRotateAroundPoint(const vector3 &o, const vector3 &__v, T ang)
141  {
142  vector3 t;
143  T a = o.x;
144  T b = o.y;
145  T c = o.z;
146  T u = __v.x;
147  T v = __v.y;
148  T w = __v.z;
149  T cos_a = cos(ang);
150  T sin_a = sin(ang);
151  T inv_poo = 1.0f / (u * u + v * v + w * w);
152  t.x = a * (v * v + w * w) + u * (-b * v - c * w + u * x + v * y + w * z) + (-a * (v * v + w * w) + u * (b * v + c * w - v * y - w * z) + (v * v + w * w) * x) * cos_a +
153  sqrtf(u * u + v * v + w * w) * (-c * v + b * w - w * y + v * z) * sin_a;
154  t.x *= inv_poo;
155  t.y = b * (u * u + w * w) + v * (-a * u - c * w + u * x + v * y + w * z) + (-b * (u * u + w * w) + v * (a * u + c * w - u * x - w * z) + (u * u + w * w) * y) * cos_a +
156  sqrtf(u * u + v * v + w * w) * (-c * u - a * w + w * x - u * z) * sin_a;
157  t.y *= inv_poo;
158  t.z = c * (u * u + v * v) + w * (-a * u + b * v + u * x + v * y + w * z) + (-c * (u * u + v * v) + w * (a * u + b * v - u * x - v * y) + (u * u + v * v) * z) * cos_a +
159  sqrtf(u * u + v * v + w * w) * (-b * u + a * v - v * x + u * y) * sin_a;
160  t.z *= inv_poo;
161  *this = t;
162  }
163 
164  /* Rotate this vector about origin, in axis defined by v. */
165  void ArbRotate(const vector3 &__v, T ang)
166  {
167  vector3 t;
168  T u = __v.x;
169  T v = __v.y;
170  T w = __v.z;
171  T cos_a = cos(ang);
172  T sin_a = sin(ang);
173  T inv_poo = 1.0f / (u * u + v * v + w * w);
174  t.x = u * (u * x + v * y + w * z) + (u * (-v * y - w * z) + (v * v + w * w) * x) * cos_a +
175  sqrtf(u * u + v * v + w * w) * (-w * y + v * z) * sin_a;
176  t.x *= inv_poo;
177  t.y = v * (u * x + v * y + w * z) + (v * (-u * x - w * z) + (u * u + w * w) * y) * cos_a +
178  sqrtf(u * u + v * v + w * w) * (w * x - u * z) * sin_a;
179  t.y *= inv_poo;
180  t.z = w * (u * x + v * y + w * z) + (w * (-u * x - v * y) + (u * u + v * v) * z) * cos_a +
181  sqrtf(u * u + v * v + w * w) * (-v * x + u * y) * sin_a;
182  t.z *= inv_poo;
183  *this = t;
184  }
185 
186  void xy(const vector2<T> &v2)
187  {
188  x = v2.x;
189  y = v2.y;
190  }
191  void xz(const vector2<T> &v2)
192  {
193  x = v2.x;
194  z = v2.y;
195  }
196  void yz(const vector2<T> &v2)
197  {
198  y = v2.x;
199  z = v2.y;
200  }
201 
202  vector2<T> xy() { return vector2<T>(x, y); }
203  vector2<T> xz() { return vector2<T>(x, z); }
204  vector2<T> yz() { return vector2<T>(y, z); }
205  vector2<T> yx() { return vector2<T>(y, x); }
206  vector2<T> zx() { return vector2<T>(z, x); }
207 };
208 
209 // These are here in this manner to enforce that only float and double versions are possible.
210 template <>
211 inline vector3<float>::vector3(const vector2f &v, float t) :
212  x(v.x),
213  y(v.y),
214  z(t)
215 {}
216 template <>
217 inline vector3<float>::vector3(const vector3<double> &v) :
218  x(float(v.x)),
219  y(float(v.y)),
220  z(float(v.z))
221 {}
222 template <>
223 inline vector3<double>::vector3(const vector3<float> &v) :
224  x(v.x),
225  y(v.y),
226  z(v.z)
227 {}
228 template <>
229 inline vector3<double>::vector3(const vector2f &v, double t) :
230  x(v.x),
231  y(v.y),
232  z(t)
233 {}
234 template <>
235 inline vector3<float>::vector3(float val) :
236  x(val),
237  y(val),
238  z(val)
239 {}
240 template <>
241 inline vector3<double>::vector3(double val) :
242  x(val),
243  y(val),
244  z(val)
245 {}
246 template <>
247 inline vector3<float>::vector3(float _x, float _y, float _z) :
248  x(_x),
249  y(_y),
250  z(_z)
251 {}
252 template <>
253 inline vector3<double>::vector3(double _x, double _y, double _z) :
254  x(_x),
255  y(_y),
256  z(_z)
257 {}
258 template <>
259 inline vector3<float>::vector3(const float vals[3]) :
260  x(vals[0]),
261  y(vals[1]),
262  z(vals[2])
263 {}
264 template <>
265 inline vector3<float>::vector3(const double vals[3]) :
266  x(float(vals[0])),
267  y(float(vals[1])),
268  z(float(vals[2]))
269 {}
270 template <>
271 inline vector3<double>::vector3(const float vals[3]) :
272  x(vals[0]),
273  y(vals[1]),
274  z(vals[2])
275 {}
276 template <>
277 inline vector3<double>::vector3(const double vals[3]) :
278  x(vals[0]),
279  y(vals[1]),
280  z(vals[2])
281 {}
282 
283 // #pragma pack()
284 
287 
288 #endif /* _VECTOR3_H */
bool is_equal_exact(float a, float b)
Definition: FloatComparison.h:112
double val
Definition: PrecalcPath.cpp:40
T y
Definition: vector2.h:26
T x
Definition: vector2.h:26
Definition: vector3.h:16
T Dot(const vector3 &b) const
Definition: vector3.h:114
vector2< T > xy()
Definition: vector3.h:202
vector3 operator-(const vector3 &a) const
Definition: vector3.h:80
vector2< T > xz()
Definition: vector3.h:203
T y
Definition: vector3.h:18
void xy(const vector2< T > &v2)
Definition: vector3.h:186
vector3(T _x, T _y, T _z)
void ArbRotateAroundPoint(const vector3 &o, const vector3 &__v, T ang)
Definition: vector3.h:140
void Print() const
Definition: vector3.h:137
vector3 & operator*=(const float a)
Definition: vector3.h:50
friend vector3 operator/(const vector3 &a, const float scalar)
Definition: vector3.h:102
const T & operator[](const size_t i) const
Definition: vector3.h:32
T LengthSqr() const
Definition: vector3.h:116
vector3 Lerp(const vector3 &b, const double percent) const
Definition: vector3.h:117
vector3 & operator*=(const double a)
Definition: vector3.h:57
T x
Definition: vector3.h:18
friend vector3 operator*(const vector3 &a, const T scalar)
Definition: vector3.h:98
vector3 NormalizedSafe() const
Definition: vector3.h:126
friend vector3 operator*(const vector3 &a, const vector3 &b)
Definition: vector3.h:97
T & operator[](const size_t i)
Definition: vector3.h:33
vector3 & operator-=(const vector3 &a)
Definition: vector3.h:43
friend vector3 operator/(const vector3 &a, const double scalar)
Definition: vector3.h:107
vector3 & operator/=(const float a)
Definition: vector3.h:64
vector2< T > zx()
Definition: vector3.h:206
vector3()=default
void xz(const vector2< T > &v2)
Definition: vector3.h:191
vector3(const T vals[3])
vector3(T val)
T Length() const
Definition: vector3.h:115
vector3 & operator/=(const double a)
Definition: vector3.h:72
vector2< T > yz()
Definition: vector3.h:204
friend vector3 operator-(const T scalar, const vector3 &a)
Definition: vector3.h:95
T z
Definition: vector3.h:18
friend vector3 operator*(const T scalar, const vector3 &a)
Definition: vector3.h:100
void ArbRotate(const vector3 &__v, T ang)
Definition: vector3.h:165
vector3 operator-() const
Definition: vector3.h:81
void yz(const vector2< T > &v2)
Definition: vector3.h:196
vector3 & operator+=(const vector3 &a)
Definition: vector3.h:36
vector2< T > yx()
Definition: vector3.h:205
friend vector3 operator+(const vector3 &a, const T &scalar)
Definition: vector3.h:92
bool ExactlyEqual(const vector3 &a) const
Definition: vector3.h:87
bool operator==(const vector3 &a) const
Definition: vector3.h:83
vector3 Normalized() const
Definition: vector3.h:121
friend vector3 operator+(const T scalar, const vector3 &a)
Definition: vector3.h:93
vector3(const vector3< typename other_floating_type< T >::type > &v)
friend vector3 operator-(const vector3 &a, const T &scalar)
Definition: vector3.h:94
vector3 Cross(const vector3 &b) const
Definition: vector3.h:113
vector3 operator+(const vector3 &a) const
Definition: vector3.h:35
vector3(const typename other_floating_type< T >::type vals[3])
vector3(const vector2f &v, T t)
Definition: vector2.h:13
vector3< float > vector3f
Definition: vector3.h:285
vector3< double > vector3d
Definition: vector3.h:286