Pioneer
vector3.h
Go to the documentation of this file.
1 // Copyright © 2008-2023 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 alignas(sizeof(T)) 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  friend vector3 operator/(const T scalar, const vector3 &a)
113  {
114  return vector3(scalar / a.x, scalar / a.y, scalar / a.z);
115  }
116 
117  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); }
118  T Dot(const vector3 &b) const { return x * b.x + y * b.y + z * b.z; }
119  T Length() const { return sqrt(x * x + y * y + z * z); }
120  T LengthSqr() const { return x * x + y * y + z * z; }
121  vector3 Lerp(const vector3 &b, const double percent) const
122  {
123  return *this + percent * (b - *this);
124  }
126  {
127  const T l = 1.0f / sqrt(x * x + y * y + z * z);
128  return vector3(x * l, y * l, z * l);
129  }
131  {
132  const T lenSqr = x * x + y * y + z * z;
133  if (lenSqr < 1e-18) // sqrt(lenSqr) < 1e-9
134  return vector3(1, 0, 0);
135  else {
136  const T l = sqrt(lenSqr);
137  return vector3(x / l, y / l, z / l);
138  }
139  }
140 
141  void Print() const { printf("v(%f,%f,%f)\n", x, y, z); }
142 
143  /* Rotate this vector about point o, in axis defined by v. */
144  void ArbRotateAroundPoint(const vector3 &o, const vector3 &__v, T ang)
145  {
146  vector3 t;
147  T a = o.x;
148  T b = o.y;
149  T c = o.z;
150  T u = __v.x;
151  T v = __v.y;
152  T w = __v.z;
153  T cos_a = cos(ang);
154  T sin_a = sin(ang);
155  T inv_poo = 1.0f / (u * u + v * v + w * w);
156  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 +
157  sqrtf(u * u + v * v + w * w) * (-c * v + b * w - w * y + v * z) * sin_a;
158  t.x *= inv_poo;
159  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 +
160  sqrtf(u * u + v * v + w * w) * (-c * u - a * w + w * x - u * z) * sin_a;
161  t.y *= inv_poo;
162  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 +
163  sqrtf(u * u + v * v + w * w) * (-b * u + a * v - v * x + u * y) * sin_a;
164  t.z *= inv_poo;
165  *this = t;
166  }
167 
168  /* Rotate this vector about origin, in axis defined by v. */
169  void ArbRotate(const vector3 &__v, T ang)
170  {
171  vector3 t;
172  T u = __v.x;
173  T v = __v.y;
174  T w = __v.z;
175  T cos_a = cos(ang);
176  T sin_a = sin(ang);
177  T inv_poo = 1.0f / (u * u + v * v + w * w);
178  t.x = u * (u * x + v * y + w * z) + (u * (-v * y - w * z) + (v * v + w * w) * x) * cos_a +
179  sqrtf(u * u + v * v + w * w) * (-w * y + v * z) * sin_a;
180  t.x *= inv_poo;
181  t.y = v * (u * x + v * y + w * z) + (v * (-u * x - w * z) + (u * u + w * w) * y) * cos_a +
182  sqrtf(u * u + v * v + w * w) * (w * x - u * z) * sin_a;
183  t.y *= inv_poo;
184  t.z = w * (u * x + v * y + w * z) + (w * (-u * x - v * y) + (u * u + v * v) * z) * cos_a +
185  sqrtf(u * u + v * v + w * w) * (-v * x + u * y) * sin_a;
186  t.z *= inv_poo;
187  *this = t;
188  }
189 
190  void xy(const vector2<T> &v2)
191  {
192  x = v2.x;
193  y = v2.y;
194  }
195  void xz(const vector2<T> &v2)
196  {
197  x = v2.x;
198  z = v2.y;
199  }
200  void yz(const vector2<T> &v2)
201  {
202  y = v2.x;
203  z = v2.y;
204  }
205 
206  vector2<T> xy() { return vector2<T>(x, y); }
207  vector2<T> xz() { return vector2<T>(x, z); }
208  vector2<T> yz() { return vector2<T>(y, z); }
209  vector2<T> yx() { return vector2<T>(y, x); }
210  vector2<T> zx() { return vector2<T>(z, x); }
211 };
212 
213 // These are here in this manner to enforce that only float and double versions are possible.
214 template <>
215 inline vector3<float>::vector3(const vector2f &v, float t) :
216  x(v.x),
217  y(v.y),
218  z(t)
219 {}
220 template <>
221 inline vector3<float>::vector3(const vector3<double> &v) :
222  x(float(v.x)),
223  y(float(v.y)),
224  z(float(v.z))
225 {}
226 template <>
227 inline vector3<double>::vector3(const vector3<float> &v) :
228  x(v.x),
229  y(v.y),
230  z(v.z)
231 {}
232 template <>
233 inline vector3<double>::vector3(const vector2f &v, double t) :
234  x(v.x),
235  y(v.y),
236  z(t)
237 {}
238 template <>
239 inline vector3<float>::vector3(float val) :
240  x(val),
241  y(val),
242  z(val)
243 {}
244 template <>
245 inline vector3<double>::vector3(double val) :
246  x(val),
247  y(val),
248  z(val)
249 {}
250 template <>
251 inline vector3<float>::vector3(float _x, float _y, float _z) :
252  x(_x),
253  y(_y),
254  z(_z)
255 {}
256 template <>
257 inline vector3<double>::vector3(double _x, double _y, double _z) :
258  x(_x),
259  y(_y),
260  z(_z)
261 {}
262 template <>
263 inline vector3<float>::vector3(const float vals[3]) :
264  x(vals[0]),
265  y(vals[1]),
266  z(vals[2])
267 {}
268 template <>
269 inline vector3<float>::vector3(const double vals[3]) :
270  x(float(vals[0])),
271  y(float(vals[1])),
272  z(float(vals[2]))
273 {}
274 template <>
275 inline vector3<double>::vector3(const float vals[3]) :
276  x(vals[0]),
277  y(vals[1]),
278  z(vals[2])
279 {}
280 template <>
281 inline vector3<double>::vector3(const double vals[3]) :
282  x(vals[0]),
283  y(vals[1]),
284  z(vals[2])
285 {}
286 
287 #pragma pack()
288 
291 
292 // ensure both packing and structure alignment match the constraints we have set
293 static_assert(alignof(vector3d) == 8);
294 static_assert(offsetof(vector3d, y) == 8);
295 static_assert(offsetof(vector3d, z) == 16);
296 
297 static_assert(alignof(vector3f) == 4);
298 static_assert(offsetof(vector3f, y) == 4);
299 static_assert(offsetof(vector3f, z) == 8);
300 
301 #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:118
vector2< T > xy()
Definition: vector3.h:206
vector3 operator-(const vector3 &a) const
Definition: vector3.h:80
vector2< T > xz()
Definition: vector3.h:207
T y
Definition: vector3.h:18
void xy(const vector2< T > &v2)
Definition: vector3.h:190
vector3(T _x, T _y, T _z)
void ArbRotateAroundPoint(const vector3 &o, const vector3 &__v, T ang)
Definition: vector3.h:144
void Print() const
Definition: vector3.h:141
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:120
vector3 Lerp(const vector3 &b, const double percent) const
Definition: vector3.h:121
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:130
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:210
vector3()=default
void xz(const vector2< T > &v2)
Definition: vector3.h:195
vector3(const T vals[3])
vector3(T val)
T Length() const
Definition: vector3.h:119
vector3 & operator/=(const double a)
Definition: vector3.h:72
vector2< T > yz()
Definition: vector3.h:208
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:169
friend vector3 operator/(const T scalar, const vector3 &a)
Definition: vector3.h:112
vector3 operator-() const
Definition: vector3.h:81
void yz(const vector2< T > &v2)
Definition: vector3.h:200
vector3 & operator+=(const vector3 &a)
Definition: vector3.h:36
vector2< T > yx()
Definition: vector3.h:209
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:125
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:117
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:289
vector3< double > vector3d
Definition: vector3.h:290