VIPRA Documentation
Loading...
Searching...
No Matches
f3d.hpp
1#pragma once
2
3#include <cassert>
4#include <cmath>
5#include <limits>
6#include <random>
7#include <stdexcept>
8#include <vector>
9
10#include "vipra/concepts/numeric.hpp"
11#include "vipra/macros/performance.hpp"
12#include "vipra/random/random.hpp"
13#include "vipra/types/float.hpp"
14
15#define F3D_FUNC [[nodiscard]] __attribute__((always_inline)) constexpr
16#define F3D_FUNC_W_DISCARD __attribute__((always_inline)) constexpr
17
18// TODO(rolland): do we need a 3d point class?
19// - we can use a 2d point and in the case of multiple stories we can use a 3d point?
20// - maybe an f2d with a small integer for the story?
21
22namespace VIPRA {
23template <class type_t>
24concept F3D_IDX = std::is_arithmetic_v<std::remove_reference_t<type_t>>;
25
26// NOLINTNEXTLINE (rolland) Keeping f3d from before format changes : ignore(readability-identifier-naming)
27struct f3d {
28 VIPRA::f_pnt x, y, z;
29
30 ~f3d() = default;
31 F3D_FUNC explicit f3d() noexcept : x(0), y(0), z(0) {}
32 F3D_FUNC explicit f3d(VIPRA::f_pnt valX) noexcept : x(valX), y(0), z(0) {}
33 F3D_FUNC explicit f3d(VIPRA::f_pnt valX, VIPRA::f_pnt valY) noexcept
34 : x(valX), y(valY), z(0)
35 {
36 }
37 F3D_FUNC explicit f3d(VIPRA::f_pnt valX, VIPRA::f_pnt valY, VIPRA::f_pnt valZ) noexcept
38 : x(valX), y(valY), z(valZ)
39 {
40 }
41 F3D_FUNC f3d(f3d const& other) noexcept = default;
42 F3D_FUNC f3d(f3d&& other) noexcept = default;
43 F3D_FUNC_W_DISCARD auto operator=(f3d const& other) noexcept -> f3d& = default;
44 F3D_FUNC_W_DISCARD auto operator=(f3d&& other) noexcept -> f3d& = default;
45
46 [[nodiscard]] __attribute__((always_inline)) static auto random(
47 VIPRA::f_pnt magnitude, VIPRA::Random::Engine& engine) -> VIPRA::f3d
48 {
49 std::uniform_real_distribution<VIPRA::f_pnt> dist{-1.0, 1.0};
50 VIPRA::f3d retVal{dist(engine), dist(engine)};
51 return retVal.unit() * magnitude;
52 }
53
54 template <F3D_IDX idx_t>
55 F3D_FUNC auto operator[](idx_t index) -> VIPRA::f_pnt&
56 {
57 switch ( index ) {
58 case 0:
59 return x;
60 case 1:
61 return y;
62 case 2:
63 return z;
64 case 'x':
65 return x;
66 case 'y':
67 return y;
68 case 'z':
69 return z;
70 default:
71 throw std::out_of_range("Attempt to access invalid index on VIPRA::f3d");
72 }
73 }
74
75 template <F3D_IDX idx_t>
76 F3D_FUNC auto operator[](idx_t index) const -> VIPRA::f_pnt
77 {
78 switch ( index ) {
79 case 0:
80 return x;
81 case 1:
82 return y;
83 case 2:
84 return z;
85 case 'x':
86 return x;
87 case 'y':
88 return y;
89 case 'z':
90 return z;
91 default:
92 throw std::out_of_range("Attempt to access invalid index on VIPRA::f3d");
93 }
94 }
95
96 template <Concepts::Numeric data_t>
97 F3D_FUNC auto operator*(data_t&& multiplier) const noexcept -> f3d
98 {
99 return f3d{x, y, z} *= std::forward<data_t>(multiplier);
100 }
101 template <Concepts::Numeric data_t>
102 F3D_FUNC_W_DISCARD auto operator*=(data_t&& multiplier) noexcept -> f3d&
103 {
104 x *= multiplier;
105 y *= multiplier;
106 z *= multiplier;
107 return *this;
108 }
109
110 template <Concepts::Numeric data_t>
111 F3D_FUNC auto operator/(data_t&& divisor) const noexcept -> f3d
112 {
113 assert(divisor != 0);
114
115 return f3d{x, y, z} /= std::forward<data_t>(divisor);
116 }
117 template <Concepts::Numeric data_t>
118 F3D_FUNC_W_DISCARD auto operator/=(data_t&& divisor) noexcept -> f3d&
119 {
120 assert(divisor != 0);
121
122 x /= divisor;
123 y /= divisor;
124 z /= divisor;
125 return *this;
126 }
127
128 F3D_FUNC auto operator-(f3d const& other) const noexcept -> f3d
129 {
130 return f3d{x - other.x, y - other.y, z - other.z};
131 }
132 F3D_FUNC auto operator-(f3d&& other) const noexcept -> f3d
133 {
134 return f3d{x - other.x, y - other.y, z - other.z};
135 }
136 F3D_FUNC auto operator+(f3d const& other) const noexcept -> f3d
137 {
138 return f3d{x + other.x, y + other.y, z + other.z};
139 }
140 F3D_FUNC auto operator+(f3d&& other) const noexcept -> f3d
141 {
142 return f3d{x + other.x, y + other.y, z + other.z};
143 }
144
145 F3D_FUNC_W_DISCARD auto operator+=(f3d const& other) noexcept -> f3d&
146 {
147 x += other.x;
148 y += other.y;
149 z += other.z;
150 return *this;
151 }
152 F3D_FUNC_W_DISCARD auto operator+=(f3d&& other) noexcept -> f3d&
153 {
154 x += other.x;
155 y += other.y;
156 z += other.z;
157 return *this;
158 }
159
160 F3D_FUNC_W_DISCARD auto operator-=(f3d const& other) noexcept -> f3d&
161 {
162 x -= other.x;
163 y -= other.y;
164 z -= other.z;
165 return *this;
166 }
167 F3D_FUNC_W_DISCARD auto operator-=(f3d&& other) noexcept -> f3d&
168 {
169 x -= other.x;
170 y -= other.y;
171 z -= other.z;
172 return *this;
173 }
174
175 F3D_FUNC auto distance_to_sqrd(f3d const& other) const noexcept -> VIPRA::f_pnt
176 {
177 const VIPRA::f_pnt deltaX = other.x - x;
178 const VIPRA::f_pnt deltaY = other.y - y;
179 const VIPRA::f_pnt deltaZ = other.z - z;
180
181 return (deltaX * deltaX) + (deltaY * deltaY) + (deltaZ * deltaZ);
182 }
183
184 F3D_FUNC auto distance_to(f3d const& other) const -> VIPRA::f_pnt
185 {
186 const VIPRA::f_pnt deltaX = other.x - x;
187 const VIPRA::f_pnt deltaY = other.y - y;
188 const VIPRA::f_pnt deltaZ = other.z - z;
189
190 return std::sqrt((deltaX * deltaX) + (deltaY * deltaY) + (deltaZ * deltaZ));
191 }
192
193 F3D_FUNC auto distance_to(f3d&& other) const -> VIPRA::f_pnt
194 {
195 const VIPRA::f_pnt deltaX = other.x - x;
196 const VIPRA::f_pnt deltaY = other.y - y;
197 const VIPRA::f_pnt deltaZ = other.z - z;
198
199 return std::sqrt((deltaX * deltaX) + (deltaY * deltaY) + (deltaZ * deltaZ));
200 }
201
202 F3D_FUNC auto operator==(f3d const& other) const noexcept -> bool
203 {
204 return (x == other.x && y == other.y && z == other.z);
205 }
206 F3D_FUNC auto operator==(f3d&& other) const noexcept -> bool
207 {
208 return (x == other.x && y == other.y && z == other.z);
209 }
210
211 F3D_FUNC auto operator!=(f3d const& other) const noexcept -> bool
212 {
213 return (x != other.x || y != other.y || z != other.z);
214 }
215 F3D_FUNC auto operator!=(f3d&& other) const noexcept -> bool
216 {
217 return (x != other.x || y != other.y || z != other.z);
218 }
219
220 F3D_FUNC auto operator-() const noexcept -> f3d { return f3d{-x, -y, -z}; }
221
227 F3D_FUNC auto unit() const noexcept -> f3d
228 {
229 if ( x == 0 && y == 0 && z == 0 ) {
230 return f3d{0, 0, 0};
231 }
232 return f3d{x, y, z} / mag();
233 }
234
240 F3D_FUNC auto mag_sqrd() const noexcept -> VIPRA::f_pnt
241 {
242 return (x * x) + (y * y) + (z * z);
243 }
244
250 F3D_FUNC auto mag() const noexcept -> VIPRA::f_pnt
251 {
252 return std::sqrt((x * x) + (y * y) + (z * z));
253 }
254
261 F3D_FUNC auto dot(f3d const& other) const noexcept -> VIPRA::f_pnt
262 {
263 return (x * other.x) + (y * other.y) + (z * other.z);
264 }
265
272 F3D_FUNC auto cross(f3d const& other) const noexcept -> f3d
273 {
274 return f3d{(y * other.z) - (z * other.y), (z * other.x) - (x * other.z),
275 (x * other.y) - (y * other.x)};
276 }
277
283 [[nodiscard]] VIPRA_INLINE auto to_string() const -> std::string
284 {
285 return std::string{"("} + std::to_string(x) + ", " + std::to_string(y) + ", " +
286 std::to_string(z) + ")";
287 }
288};
289
290template <Concepts::Numeric data_t>
291F3D_FUNC auto operator*(data_t&& multiplier, f3d const& other) noexcept -> f3d
292{
293 return f3d{other.x * multiplier, other.y * multiplier, other.z * multiplier};
294}
295
296using f3dVec = std::vector<f3d>;
297
298constexpr f3d _emptyf3d_ = // NOLINT
299 VIPRA::f3d{std::numeric_limits<VIPRA::f_pnt>::max(),
300 std::numeric_limits<VIPRA::f_pnt>::max(),
301 std::numeric_limits<VIPRA::f_pnt>::max()};
302
303extern const f3dVec emptyf3d_vec; // NOLINT
304} // namespace VIPRA
Psuedo Random number engine.
Definition random.hpp:22
Definition f3d.hpp:24
Definition f3d.hpp:27
VIPRA_INLINE auto to_string() const -> std::string
Returns the string representation of the f3d.
Definition f3d.hpp:283
F3D_FUNC auto cross(f3d const &other) const noexcept -> f3d
Returns the cross product between two f3ds.
Definition f3d.hpp:272
F3D_FUNC auto mag() const noexcept -> VIPRA::f_pnt
Returns the vectors magnitude.
Definition f3d.hpp:250
F3D_FUNC auto unit() const noexcept -> f3d
Returns the unit vector in the direction of the f3d.
Definition f3d.hpp:227
F3D_FUNC auto mag_sqrd() const noexcept -> VIPRA::f_pnt
Returns vector magnitude^2.
Definition f3d.hpp:240
F3D_FUNC auto dot(f3d const &other) const noexcept -> VIPRA::f_pnt
Returns the dot product between two f3ds.
Definition f3d.hpp:261