NcEngine
Vector.h
Go to the documentation of this file.
1
5#pragma once
6
7#include "Math.h"
8
9namespace nc
10{
12struct Vector2
13{
14 float x, y;
15
16 constexpr explicit Vector2() noexcept : x{0.0f}, y{0.0f} {}
17 constexpr explicit Vector2(float x_, float y_) noexcept : x{x_}, y{y_} {}
18 static constexpr Vector2 Splat(float v) noexcept { return Vector2{v, v}; }
19 static constexpr Vector2 Zero() noexcept { return Vector2{ 0, 0}; }
20 static constexpr Vector2 One() noexcept { return Vector2{ 1, 1}; }
21 static constexpr Vector2 Up() noexcept { return Vector2{ 0, 1}; }
22 static constexpr Vector2 Down() noexcept { return Vector2{ 0,-1}; }
23 static constexpr Vector2 Left() noexcept { return Vector2{-1, 0}; }
24 static constexpr Vector2 Right() noexcept { return Vector2{ 1, 0}; }
25};
26
28struct Vector3
29{
30 float x, y, z;
31
32 constexpr Vector3() noexcept : x{0.0f}, y{0.0f}, z{0.0f} {}
33 constexpr explicit Vector3(float x_, float y_, float z_) noexcept : x{x_}, y{y_}, z{z_} {}
34 constexpr explicit Vector3(const Vector2& v, float z_) noexcept : x{v.x}, y{v.y}, z{z_} {}
35 static constexpr Vector3 Splat(float v) noexcept { return Vector3{v, v, v}; }
36 static constexpr Vector3 Zero() noexcept { return Vector3{ 0, 0, 0}; }
37 static constexpr Vector3 One() noexcept { return Vector3{ 1, 1, 1}; }
38 static constexpr Vector3 Up() noexcept { return Vector3{ 0, 1, 0}; }
39 static constexpr Vector3 Down() noexcept { return Vector3{ 0,-1, 0}; }
40 static constexpr Vector3 Left() noexcept { return Vector3{-1, 0, 0}; }
41 static constexpr Vector3 Right() noexcept { return Vector3{ 1, 0, 0}; }
42 static constexpr Vector3 Front() noexcept { return Vector3{ 0, 0, 1}; }
43 static constexpr Vector3 Back() noexcept { return Vector3{ 0, 0,-1}; }
44};
45
47struct Vector4
48{
49 float x, y, z, w;
50
51 constexpr explicit Vector4() noexcept : x{0.0f}, y{0.0f}, z{0.0f}, w{0.0f} {}
52 constexpr explicit Vector4(float x_, float y_, float z_, float w_) noexcept : x{x_}, y{y_}, z{z_}, w{w_} {}
53 constexpr explicit Vector4(const Vector3& v, float w_) noexcept : x{v.x}, y{v.y}, z{v.z}, w{w_} {}
54 static constexpr Vector4 Splat(float v) noexcept { return Vector4{v, v, v, v}; }
55 static constexpr Vector4 Zero() noexcept { return Vector4(0, 0, 0, 0); }
56 static constexpr Vector4 One() noexcept { return Vector4(1, 1, 1, 1); }
57};
58
60constexpr auto operator ==(const Vector2& lhs, const Vector2& rhs) noexcept -> bool;
61constexpr auto operator !=(const Vector2& lhs, const Vector2& rhs) noexcept -> bool;
62constexpr auto operator +(const Vector2& lhs, const Vector2& rhs) noexcept -> Vector2;
63constexpr auto operator -(const Vector2& lhs, const Vector2& rhs) noexcept -> Vector2;
64constexpr auto operator *(const Vector2& vec, float scalar) noexcept -> Vector2;
65constexpr auto operator *(float scalar, const Vector2& vec) noexcept -> Vector2;
66constexpr auto operator /(const Vector2& vec, float scalar) noexcept -> Vector2;
67constexpr auto operator -(const Vector2& vec) noexcept -> Vector2;
68constexpr auto Dot(const Vector2& lhs, const Vector2& rhs) noexcept -> float;
69constexpr auto HadamardProduct(const Vector2& lhs, const Vector2& rhs) noexcept -> Vector2;
70constexpr auto SquareMagnitude(const Vector2& vec) noexcept -> float;
71inline auto Magnitude(const Vector2& vec) noexcept -> float;
72inline auto Normalize(const Vector2& vec) noexcept -> Vector2;
73constexpr auto SquareDistance(const Vector2& lhs, const Vector2& rhs) noexcept -> float;
74inline auto Distance(const Vector2& lhs, const Vector2& rhs) noexcept -> float;
75constexpr auto HasAnyZeroElement(const Vector2& vec) noexcept -> bool;
76constexpr auto HasUniformElements(const Vector2& vec) noexcept -> bool;
77
79constexpr auto operator ==(const Vector3& lhs, const Vector3& rhs) noexcept -> bool;
80constexpr auto operator !=(const Vector3& lhs, const Vector3& rhs) noexcept -> bool;
81constexpr auto operator +(const Vector3& lhs, const Vector3& rhs) noexcept -> Vector3;
82constexpr auto operator -(const Vector3& lhs, const Vector3& rhs) noexcept -> Vector3;
83constexpr auto operator *(const Vector3& vec, float scalar) noexcept -> Vector3;
84constexpr auto operator *(float scalar, const Vector3& vec) noexcept -> Vector3;
85constexpr auto operator /(const Vector3& vec, float scalar) noexcept -> Vector3;
86constexpr auto operator -(const Vector3& vec) noexcept -> Vector3;
87constexpr auto operator +=(Vector3& lhs, const Vector3& rhs) noexcept -> Vector3&;
88constexpr auto operator -=(Vector3& lhs, const Vector3& rhs) noexcept -> Vector3&;
89constexpr auto operator *=(Vector3& lhs, float rhs) noexcept -> Vector3&;
90constexpr auto operator /=(Vector3& lhs, float rhs) noexcept -> Vector3&;
91constexpr auto Dot(const Vector3& lhs, const Vector3& rhs) noexcept -> float;
92constexpr auto CrossProduct(const Vector3& lhs, const Vector3& rhs) noexcept -> Vector3;
93constexpr auto TripleCrossProduct(const Vector3& a, const Vector3& b, const Vector3& c) noexcept -> Vector3;
94constexpr auto HadamardProduct(const Vector3& lhs, const Vector3& rhs) noexcept -> Vector3;
95constexpr auto SquareMagnitude(const Vector3& vec) noexcept -> float;
96inline auto Magnitude(const Vector3& vec) noexcept -> float;
97inline auto Normalize(const Vector3& vec) noexcept -> Vector3;
98constexpr auto SquareDistance(const Vector3& lhs, const Vector3& rhs) noexcept -> float;
99inline auto Distance(const Vector3& lhs, const Vector3& rhs) noexcept -> float;
100constexpr auto HasAnyZeroElement(const Vector3& vec) noexcept -> bool;
101constexpr auto HasUniformElements(const Vector3& vec) noexcept -> bool;
102inline auto OrthogonalTo(const Vector3& vec) noexcept -> Vector3;
103inline void OrthogonalBasis(const Vector3& vec, Vector3* a, Vector3* b) noexcept;
104inline auto ClosestOrthogonal(const Vector3& target, const Vector3& reference) noexcept -> Vector3;
105
107constexpr auto operator ==(const Vector4& lhs, const Vector4& rhs) noexcept -> bool;
108constexpr auto operator !=(const Vector4& lhs, const Vector4& rhs) noexcept -> bool;
109constexpr auto operator +(const Vector4& lhs, const Vector4& rhs) noexcept -> Vector4;
110constexpr auto operator -(const Vector4& lhs, const Vector4& rhs) noexcept -> Vector4;
111constexpr auto operator *(const Vector4& vec, float scalar) noexcept -> Vector4;
112constexpr auto operator *(float scalar, const Vector4& vec) noexcept -> Vector4;
113constexpr auto operator /(const Vector4& vec, float scalar) noexcept -> Vector4;
114constexpr auto operator -(const Vector4& vec) noexcept -> Vector4;
115constexpr auto Dot(const Vector4& lhs, const Vector4& rhs) noexcept -> float;
116constexpr auto HadamardProduct(const Vector4& lhs, const Vector4& rhs) noexcept -> Vector4;
117constexpr auto SquareMagnitude(const Vector4& vec) noexcept -> float;
118inline auto Magnitude(const Vector4& vec) noexcept -> float;
119inline auto Normalize(const Vector4& vec) noexcept -> Vector4;
120constexpr auto SquareDistance(const Vector4& lhs, const Vector4& rhs) noexcept -> float;
121inline auto Distance(const Vector4& lhs, const Vector4& rhs) noexcept -> float;
122constexpr auto HasAnyZeroElement(const Vector4& vec) noexcept -> bool;
123constexpr auto HasUniformElements(const Vector4& vec) noexcept -> bool;
124constexpr auto ToVector3(const Vector4& vec) noexcept -> Vector3;
125
126/* Vector2 Implementation */
127constexpr bool operator ==(const Vector2& lhs, const Vector2& rhs) noexcept
128{
129 return FloatEqual(lhs.x, rhs.x) && FloatEqual(lhs.y, rhs.y);
130}
131
132constexpr bool operator !=(const Vector2& lhs, const Vector2& rhs) noexcept
133{
134 return !(lhs == rhs);
135}
136
137constexpr Vector2 operator +(const Vector2& lhs, const Vector2& rhs) noexcept
138{
139 return Vector2(lhs.x + rhs.x, lhs.y + rhs.y);
140}
141
142constexpr Vector2 operator -(const Vector2& lhs, const Vector2& rhs) noexcept
143{
144 return Vector2(lhs.x - rhs.x, lhs.y - rhs.y);
145}
146
147constexpr Vector2 operator *(const Vector2& vec, float scalar) noexcept
148{
149 return Vector2(vec.x * scalar, vec.y * scalar);
150}
151
152constexpr Vector2 operator *(float scalar, const Vector2& vec) noexcept
153{
154 return vec * scalar;
155}
156
157constexpr Vector2 operator /(const Vector2& vec, float scalar) noexcept
158{
159 return Vector2(vec.x / scalar, vec.y / scalar);
160}
161
162constexpr Vector2 operator -(const Vector2& vec) noexcept
163{
164 return vec * -1.0f;
165}
166
167constexpr float Dot(const Vector2& lhs, const Vector2& rhs) noexcept
168{
169 return lhs.x * rhs.x + lhs.y * rhs.y;
170}
171
172constexpr Vector2 HadamardProduct(const Vector2& lhs, const Vector2& rhs) noexcept
173{
174 return Vector2{lhs.x * rhs.x, lhs.y * rhs.y};
175}
176
177constexpr float SquareMagnitude(const Vector2& vec) noexcept
178{
179 return Dot(vec, vec);
180}
181
182float Magnitude(const Vector2& vec) noexcept
183{
184 return sqrtf(SquareMagnitude(vec));
185}
186
187Vector2 Normalize(const Vector2& vec) noexcept
188{
189 return vec == Vector2::Zero() ? Vector2::Zero() : vec / Magnitude(vec);
190}
191
192constexpr float SquareDistance(const Vector2& lhs, const Vector2& rhs) noexcept
193{
194 return SquareMagnitude(lhs - rhs);
195}
196
197float Distance(const Vector2& lhs, const Vector2& rhs) noexcept
198{
199 return Magnitude(lhs - rhs);
200}
201
202constexpr bool HasAnyZeroElement(const Vector2& vec) noexcept
203{
204 return FloatEqual(vec.x, 0.0f) || FloatEqual(vec.y, 0.0f);
205}
206
207constexpr auto HasUniformElements(const Vector2& vec) noexcept -> bool
208{
209 return FloatEqual(vec.x, vec.y);
210}
211
212/* Vector3 Implementation */
213constexpr bool operator ==(const Vector3& lhs, const Vector3& rhs) noexcept
214{
215 return FloatEqual(lhs.x, rhs.x) && FloatEqual(lhs.y, rhs.y) && FloatEqual(lhs.z, rhs.z);
216}
217
218constexpr bool operator !=(const Vector3& lhs, const Vector3& rhs) noexcept
219{
220 return !(lhs == rhs);
221}
222
223constexpr Vector3 operator +(const Vector3& lhs, const Vector3& rhs) noexcept
224{
225 return Vector3{lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z};
226}
227
228constexpr Vector3 operator -(const Vector3& lhs, const Vector3& rhs) noexcept
229{
230 return Vector3{lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z};
231}
232
233constexpr Vector3 operator *(const Vector3& vec, float scalar) noexcept
234{
235 return Vector3{vec.x * scalar, vec.y * scalar, vec.z * scalar};
236}
237
238constexpr Vector3 operator *(float scalar, const Vector3& vec) noexcept
239{
240 return vec * scalar;
241}
242
243constexpr Vector3 operator /(const Vector3& vec, float scalar) noexcept
244{
245 return Vector3{vec.x / scalar, vec.y / scalar, vec.z / scalar};
246}
247
248constexpr Vector3 operator-(const Vector3& vec) noexcept
249{
250 return vec * -1.0f;
251}
252
253constexpr Vector3& operator +=(Vector3& lhs, const Vector3& rhs) noexcept
254{
255 lhs = lhs + rhs;
256 return lhs;
257}
258
259constexpr Vector3& operator -=(Vector3& lhs, const Vector3& rhs) noexcept
260{
261 lhs = lhs - rhs;
262 return lhs;
263}
264
265constexpr Vector3& operator *=(Vector3& lhs, float rhs) noexcept
266{
267 lhs = lhs * rhs;
268 return lhs;
269}
270
271constexpr Vector3& operator /=(Vector3& lhs, float rhs) noexcept
272{
273 lhs = lhs / rhs;
274 return lhs;
275}
276
277constexpr float Dot(const Vector3& lhs, const Vector3& rhs) noexcept
278{
279 return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
280}
281
282constexpr Vector3 CrossProduct(const Vector3& lhs, const Vector3& rhs) noexcept
283{
284 return Vector3
285 {
286 lhs.y * rhs.z - lhs.z * rhs.y,
287 lhs.z * rhs.x - lhs.x * rhs.z,
288 lhs.x * rhs.y - lhs.y * rhs.x
289 };
290}
291
292constexpr Vector3 TripleCrossProduct(const Vector3& a, const Vector3& b, const Vector3& c) noexcept
293{
294 return (b * Dot(c, a)) - (a * Dot(c, b));
295}
296
297constexpr Vector3 HadamardProduct(const Vector3& lhs, const Vector3& rhs) noexcept
298{
299 return Vector3{lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z};
300}
301
302constexpr float SquareMagnitude(const Vector3& vec) noexcept
303{
304 return Dot(vec, vec);
305}
306
307float Magnitude(const Vector3& vec) noexcept
308{
309 return sqrtf(SquareMagnitude(vec));
310}
311
312Vector3 Normalize(const Vector3& vec) noexcept
313{
314 return vec == Vector3::Zero() ? Vector3::Zero() : vec / Magnitude(vec);
315}
316
317constexpr float SquareDistance(const Vector3& lhs, const Vector3& rhs) noexcept
318{
319 return SquareMagnitude(lhs - rhs);
320}
321
322float Distance(const Vector3& lhs, const Vector3& rhs) noexcept
323{
324 return Magnitude(lhs - rhs);
325}
326
327constexpr bool HasAnyZeroElement(const Vector3& vec) noexcept
328{
329 return FloatEqual(vec.x, 0.0f) || FloatEqual(vec.y, 0.0f) || FloatEqual(vec.z, 0.0f);
330}
331
332constexpr auto HasUniformElements(const Vector3& vec) noexcept -> bool
333{
334 return FloatEqual(vec.x, vec.y) && FloatEqual(vec.x, vec.z);
335}
336
337Vector3 OrthogonalTo(const Vector3& vec) noexcept
338{
339 const float invSqrt3 = 1.0f / sqrtf(3.0f);
340 return (fabs(vec.x) >= invSqrt3) ?
341 Normalize(Vector3{vec.y, -1.0f * vec.x, 0.0f}) :
342 Normalize(Vector3{0.0f, vec.z, -1.0f * vec.y});
343}
344
345void OrthogonalBasis(const Vector3& vec, Vector3* a, Vector3* b) noexcept
346{
347 *a = OrthogonalTo(vec);
348 *b = CrossProduct(*a, vec);
349}
350
351auto ClosestOrthogonal(const Vector3& target, const Vector3& reference) noexcept -> Vector3
352{
353 constexpr auto parallelThreshold = 0.999f;
354 const auto projection = Dot(target, reference);
355 if (std::fabs(projection) < parallelThreshold)
356 {
357 return Normalize(target - reference * projection);
358 }
359
360 return OrthogonalTo(reference);
361}
362
363/* Vector 4 Implementation */
364constexpr bool operator ==(const Vector4& lhs, const Vector4& rhs) noexcept
365{
366 return FloatEqual(lhs.x, rhs.x) &&
367 FloatEqual(lhs.y, rhs.y) &&
368 FloatEqual(lhs.z, rhs.z) &&
369 FloatEqual(lhs.w, rhs.w);
370}
371
372constexpr bool operator !=(const Vector4& lhs, const Vector4& rhs) noexcept
373{
374 return !(lhs == rhs);
375}
376
377constexpr Vector4 operator +(const Vector4& lhs, const Vector4& rhs) noexcept
378{
379 return Vector4{lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w};
380}
381
382constexpr Vector4 operator -(const Vector4& lhs, const Vector4& rhs) noexcept
383{
384 return Vector4{lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w};
385}
386
387constexpr Vector4 operator *(const Vector4& vec, float scalar) noexcept
388{
389 return Vector4{vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar};
390}
391
392constexpr Vector4 operator *(float scalar, const Vector4& vec) noexcept
393{
394 return vec * scalar;
395}
396
397constexpr Vector4 operator /(const Vector4& vec, float scalar) noexcept
398{
399 return Vector4{vec.x / scalar, vec.y / scalar, vec.z / scalar, vec.w / scalar};
400}
401
402constexpr Vector4 operator -(const Vector4& vec) noexcept
403{
404 return vec * -1.0f;
405}
406
407constexpr float Dot(const Vector4& lhs, const Vector4& rhs) noexcept
408{
409 return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z + lhs.w * rhs.w;
410}
411
412constexpr Vector4 HadamardProduct(const Vector4& lhs, const Vector4& rhs) noexcept
413{
414 return Vector4{lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w};
415}
416
417constexpr float SquareMagnitude(const Vector4& vec) noexcept
418{
419 return Dot(vec, vec);
420}
421
422float Magnitude(const Vector4& vec) noexcept
423{
424 return sqrtf(SquareMagnitude(vec));
425}
426
427Vector4 Normalize(const Vector4& vec) noexcept
428{
429 return vec == Vector4::Zero() ? Vector4::Zero() : vec / Magnitude(vec);
430}
431
432constexpr float SquareDistance(const Vector4& lhs, const Vector4& rhs) noexcept
433{
434 return SquareMagnitude(lhs - rhs);
435}
436
437float Distance(const Vector4& lhs, const Vector4& rhs) noexcept
438{
439 return Magnitude(lhs - rhs);
440}
441
442constexpr bool HasAnyZeroElement(const Vector4& vec) noexcept
443{
444 return FloatEqual(vec.x, 0.0f) ||
445 FloatEqual(vec.y, 0.0f) ||
446 FloatEqual(vec.z, 0.0f) ||
447 FloatEqual(vec.w, 0.0f);
448}
449
450constexpr auto HasUniformElements(const Vector4& vec) noexcept -> bool
451{
452 return FloatEqual(vec.x, vec.y) && FloatEqual(vec.x, vec.z) && FloatEqual(vec.x, vec.w);
453}
454
455constexpr Vector3 ToVector3(const Vector4& vec) noexcept
456{
457 return Vector3{vec.x, vec.y, vec.z};
458}
459} // namespace nc
auto Normalize(const Quaternion &quat) -> Quaternion
Return a normalized quaternion.
A two component vector.
Definition: Vector.h:13
A three component vector.
Definition: Vector.h:29
A four component vector.
Definition: Vector.h:48