jaulib v1.3.8
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
vec4f.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright Gothel Software e.K.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * This Source Code Form is subject to the terms of the MIT License
8 * If a copy of the MIT was not distributed with this file,
9 * you can obtain one at https://opensource.org/license/mit/.
10 */
11
12#ifndef JAU_MATH_VEC4F_HPP_
13#define JAU_MATH_VEC4F_HPP_
14
15#include <cmath>
16#include <cstdarg>
17#include <cassert>
18#include <limits>
19#include <string>
20#include <algorithm>
21#include <initializer_list>
22
23#include <jau/float_math.hpp>
24
25#include <iostream>
26
27#include <jau/math/vec3f.hpp>
28
29namespace jau::math {
30
31 /** \addtogroup Math
32 *
33 * @{
34 */
35
36 /**
37 * 4D vector using four value_type components.
38 *
39 * Component and overall alignment is natural as sizeof(value_type),
40 * i.e. sizeof(value_type) == alignof(value_type)
41 */
42 template <typename Value_type,
43 std::enable_if_t<std::is_floating_point_v<Value_type> &&
44 sizeof(Value_type) == alignof(Value_type), bool> = true>
45 class alignas(sizeof(Value_type)) Vector4F {
46 public:
49 typedef const value_type* const_pointer;
53 typedef const value_type* const_iterator;
54
55 /** value alignment is sizeof(value_type) */
56 constexpr static int value_alignment = sizeof(value_type);
57
58 /** Number of value_type components */
59 constexpr static const size_t components = 4;
60
61 /** Size in bytes with value_alignment */
62 constexpr static const size_t byte_size = components * sizeof(value_type);
63
65
66 constexpr static const value_type zero = value_type(0);
67 constexpr static const value_type one = value_type(1);
68
73
74 constexpr Vector4F() noexcept
75 : x(zero), y(zero), z(zero), w(zero) {}
76
77 constexpr Vector4F(const value_type v) noexcept
78 : x(v), y(v), z(v), w(v) {}
79
80 constexpr Vector4F(const value_type x_, const value_type y_, const value_type z_, const value_type w_) noexcept
81 : x(x_), y(y_), z(z_), w(w_) {}
82
83 constexpr Vector4F(const Vec3& o3, const value_type w_) noexcept
84 : x(o3.x), y(o3.y), z(o3.z), w(w_) {}
85
86 constexpr Vector4F(const_iterator v) noexcept
87 : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
88
89 constexpr Vector4F(std::initializer_list<value_type> v) noexcept
90 : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
91
92 constexpr Vector4F(const Vector4F& o) noexcept = default;
93 constexpr Vector4F(Vector4F&& o) noexcept = default;
94 constexpr Vector4F& operator=(const Vector4F&) noexcept = default;
95 constexpr Vector4F& operator=(Vector4F&&) noexcept = default;
96
97 constexpr Vector4F copy() noexcept { return Vector4F(*this); }
98
99 /** Returns read-only component */
100 constexpr value_type operator[](size_t i) const noexcept {
101 assert(i < 4);
102 return (&x)[i];
103 }
104
105 explicit operator const_pointer() const noexcept { return &x; }
106 constexpr const_iterator cbegin() const noexcept { return &x; }
107
108 /** Returns writeable reference to component */
109 constexpr reference operator[](size_t i) noexcept {
110 assert(i < 4);
111 return (&x)[i];
112 }
113
114 explicit operator pointer() noexcept { return &x; }
115 constexpr iterator begin() noexcept { return &x; }
116
117 /** xyzw = this, returns xyzw. */
118 constexpr iterator get(iterator xyzw) const noexcept
119 { xyzw[0] = x; xyzw[1] = y; xyzw[2] = z; xyzw[3] = w; return xyzw; }
120
121 /** out = { this.x, this.y, this.z } dropping w, returns out. */
122 constexpr Vec3& getVec3(Vec3& out) const noexcept
123 { out.x = x; out.y = y; out.z = z; return out; }
124
125 constexpr bool operator==(const Vector4F& rhs) const noexcept {
126 if (this == &rhs) {
127 return true;
128 }
129 return jau::is_zero(x - rhs.x) && jau::is_zero(y - rhs.y) &&
130 jau::is_zero(z - rhs.z) && jau::is_zero(w - rhs.w);
131 }
132 /** TODO
133 constexpr std::strong_ordering operator<=>(const vec4f_t& rhs) const noexcept {
134 return ...
135 } */
136
137 /** this = { o, w }, returns this. */
138 constexpr Vector4F& set(const Vec3f& o, const value_type w_) noexcept
139 { x = o.x; y = o.y; z = o.z; w = w_; return *this; }
140
141 constexpr Vector4F& set(const value_type vx, const value_type vy, const value_type vz, const value_type vw) noexcept
142 { x=vx; y=vy; z=vz; w=vw; return *this; }
143
144 /** this = xyzw, returns this. */
145 constexpr Vector4F& set(const_iterator xyzw) noexcept
146 { x=xyzw[0]; y=xyzw[1]; z=xyzw[2]; z=xyzw[3]; return *this; }
147
148 /** this = this + {d.x, d.y, d.z, d.w}, component wise. Returns this. */
149 constexpr Vector4F& add(const Vector4F& d) noexcept
150 { x+=d.x; y+=d.y; z+=d.z; w+=d.w; return *this; }
151
152 /** this = this + {dx, dy, dz, dw}, component wise. Returns this. */
153 constexpr Vector4F& add(const value_type dx, const value_type dy, const value_type dz, const value_type dw) noexcept
154 { x+=dx; y+=dy; z+=dz; w+=dw; return *this; }
155
156 /** this = this * {s.x, s.y, s.z}, component wise. Returns this. */
157 constexpr Vector4F& mul(const Vector4F& s) noexcept
158 { x*=s.x; y*=s.y; z*=s.z; w*=s.w; return *this; }
159
160 /** this = this * {sx, sy, sz, sw}, component wise. Returns this. */
161 constexpr Vector4F& mul(const value_type sx, const value_type sy, const value_type sz, const value_type sw) noexcept
162 { x*=sx; y*=sy; z*=sz; w*=sw; return *this; }
163
164 /** this = this * s, component wise. Returns this. */
165 constexpr Vector4F& scale(const value_type s) noexcept
166 { x*=s; y*=s; z*=s; w*=s; return *this; }
167
168 /** this = this + rhs, component wise. Returns this. */
169 constexpr Vector4F& operator+=(const Vector4F& rhs ) noexcept {
170 x+=rhs.x; y+=rhs.y; z+=rhs.z; w+=rhs.w;
171 return *this;
172 }
173
174 /** this = this - rhs, component wise. Returns this. */
175 constexpr Vector4F& operator-=(const Vector4F& rhs ) noexcept
176 { x-=rhs.x; y-=rhs.y; z-=rhs.z; w-=rhs.w; return *this;
177 }
178
179 /**
180 * this = this * {s.x, s.y, s.z, s.w}, component wise.
181 * @param s scale factor
182 * @return this instance
183 */
184 constexpr Vector4F& operator*=(const Vector4F& s) noexcept {
185 x*=s.x; y*=s.y; z*=s.z; w*=s.w;
186 return *this;
187 }
188 /**
189 * this = this / {s.x, s.y, s.z, s.w}, component wise.
190 * @param s scale factor
191 * @return this instance
192 */
193 constexpr Vector4F& operator/=(const Vector4F& s) noexcept {
194 x/=s.x; y/=s.y; z/=s.z; w/=s.w;
195 return *this;
196 }
197
198 /**
199 * this = this * s, component wise.
200 * @param s scale factor
201 * @return this instance
202 */
203 constexpr Vector4F& operator*=(const value_type s ) noexcept
204 { x*=s; y*=s; z*=s; w*=s; return *this; }
205
206 /**
207 * this = this / s, component wise.
208 * @param s scale factor
209 * @return this instance
210 */
211 constexpr Vector4F& operator/=(const value_type s ) noexcept
212 { x/=s; y/=s; z/=s; w/=s; return *this; }
213
214 std::string toString() const noexcept { return std::to_string(x) + ", " + std::to_string(y) + ", " + std::to_string(z) + ", " + std::to_string(w); }
215
216 constexpr bool is_zero() const noexcept {
218 }
219
220 /**
221 * Return the squared length of a vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i>
222 */
223 constexpr value_type length_sq() const noexcept {
224 return x*x + y*y + z*z + w*w;
225 }
226
227 /**
228 * Return the length of a vector, a.k.a the <i>norm</i> or <i>magnitude</i>
229 */
230 constexpr value_type length() const noexcept {
231 return std::sqrt(length_sq());
232 }
233
234 /**
235 * Normalize this vector in place
236 */
237 constexpr Vector4F& normalize() noexcept {
238 const value_type lengthSq = length_sq();
239 if (jau::is_zero(lengthSq)) {
240 x = zero;
241 y = zero;
242 z = zero;
243 w = zero;
244 } else {
245 const value_type invSqr = one / std::sqrt(lengthSq);
246 x *= invSqr;
247 y *= invSqr;
248 z *= invSqr;
249 w *= invSqr;
250 }
251 return *this;
252 }
253
254 /**
255 * Return the squared distance between this vector and the given one.
256 * <p>
257 * When comparing the relative distance between two points it is usually sufficient to compare the squared
258 * distances, thus avoiding an expensive square root operation.
259 * </p>
260 */
261 constexpr value_type dist_sq(const Vector4F& o) const noexcept {
262 const value_type dx = x - o.x;
263 const value_type dy = y - o.y;
264 const value_type dz = z - o.z;
265 const value_type dw = w - o.w;
266 return dx*dx + dy*dy + dz*dz + dw*dw;
267 }
268
269 /**
270 * Return the distance between this vector and the given one.
271 */
272 constexpr value_type dist(const Vector4F& o) const noexcept {
273 return std::sqrt(dist_sq(o));
274 }
275
276 constexpr_cxx23 bool intersects(const Vector4F& o) const noexcept {
277 const value_type eps = std::numeric_limits<value_type>::epsilon();
278 if (std::abs(x - o.x) >= eps || std::abs(y - o.y) >= eps ||
279 std::abs(z - o.z) >= eps || std::abs(w - o.w) >= eps) {
280 return false;
281 }
282 return true;
283 }
284 };
285
286 template <typename T,
287 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
288 constexpr Vector4F<T> operator+(const Vector4F<T>& lhs, const Vector4F<T>& rhs) noexcept {
289 // Returning a Vector4 object from the returned reference of operator+=()
290 // may hinder copy-elision or "named return value optimization" (NRVO).
291 // return Vector4<T>(lhs) += rhs;
292
293 // Returning named object allows copy-elision (NRVO),
294 // only one object is created 'on target'.
295 Vector4F<T> r(lhs); r += rhs; return r;
296 }
297
298 template<typename T,
299 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
300 constexpr Vector4F<T> operator-(const Vector4F<T>& lhs, const Vector4F<T>& rhs ) noexcept {
301 Vector4F<T> r(lhs); r -= rhs; return r;
302 }
303
304 template<typename T,
305 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
306 constexpr Vector4F<T> operator-(const Vector4F<T>& lhs) noexcept {
307 Vector4F<T> r(lhs);
308 r *= -1;
309 return r;
310 }
311
312 template<typename T,
313 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
314 constexpr Vector4F<T> operator*(const Vector4F<T>& lhs, const T s ) noexcept {
315 Vector4F<T> r(lhs); r *= s; return r;
316 }
317
318 template<typename T,
319 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
320 constexpr Vector4F<T> operator*(const T s, const Vector4F<T>& rhs) noexcept {
321 Vector4F<T> r(rhs); r *= s; return r;
322 }
323
324 template<typename T,
325 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
326 constexpr Vector4F<T> operator/(const Vector4F<T>& lhs, const T s ) noexcept {
327 Vector4F<T> r(lhs); r /= s; return r;
328 }
329
330 template<typename T,
331 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
332 constexpr Vector4F<T> operator/(const T s, const Vector4F<T>& rhs) noexcept {
333 Vector4F<T> r(rhs);
334 r.x=s/r.x; r.y=s/r.y; r.z=s/r.z; r.w=s/r.w;
335 return r;
336 }
337
338 template<typename T,
339 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
340 constexpr Vector4F<T> min(const Vector4F<T>& lhs, const Vector4F<T>& rhs) noexcept {
341 return Vector4F<T>(std::min(lhs.x, rhs.x), std::min(lhs.y, rhs.y), std::min(lhs.z, rhs.z), std::min(lhs.w, rhs.w));
342 }
343
344 template<typename T,
345 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
346 constexpr Vector4F<T> max(const Vector4F<T>& lhs, const Vector4F<T>& rhs) noexcept {
347 return Vector4F<T>(std::max(lhs.x, rhs.x), std::max(lhs.y, rhs.y), std::max(lhs.z, rhs.z), std::max(lhs.w, rhs.w));
348 }
349
350 template<typename T,
351 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
352 constexpr Vector4F<T> abs(const Vector4F<T>& lhs) noexcept {
353 return Vector4F<T>(std::abs(lhs.x), std::abs(lhs.y), std::abs(lhs.z), std::abs(lhs.w));
354 }
355
356 /** out = { this.x, this.y, this.z } dropping w, returns out. */
357 template<typename T,
358 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
359 constexpr Vector3F<T> to_vec3(const Vector4F<T>& v) noexcept {
360 Vector3F<T> r; v.getVec3(r); return r;
361 }
362
363 template <typename T,
364 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
365 std::ostream& operator<<(std::ostream& out, const Vector4F<T>& v) noexcept {
366 return out << v.toString();
367 }
368
369 static_assert(4 == Vector4F<double>::components);
370 static_assert(sizeof(double) == Vector4F<double>::value_alignment);
371 static_assert(sizeof(double) == alignof(Vector4F<double>));
372 static_assert(sizeof(double) * 4 == Vector4F<double>::byte_size);
373 static_assert(sizeof(double) * 4 == sizeof(Vector4F<double>));
374
376 static_assert(4 == Vec4f::components);
377 static_assert(sizeof(float) == Vec4f::value_alignment);
378 static_assert(sizeof(float) == alignof(Vec4f));
379 static_assert(sizeof(float) * 4 == Vec4f::byte_size);
380 static_assert(sizeof(float) * 4 == sizeof(Vec4f));
381
382 /**
383 * Point4F alias of Vector4F
384 */
385 template <typename Value_type,
386 std::enable_if_t<std::is_floating_point_v<Value_type> &&
387 sizeof(Value_type) == alignof(Value_type), bool> = true>
389
391 static_assert(4 == Point4f::components);
392 static_assert(sizeof(float) == Point4f::value_alignment);
393 static_assert(sizeof(float) == alignof(Point4f));
394 static_assert(sizeof(float) * 4 == Point4f::byte_size);
395 static_assert(sizeof(float) * 4 == sizeof(Point4f));
396
397 /**@}*/
398
399} // namespace jau::math
400
401#endif /* JAU_MATH_VEC4F_HPP_ */
3D vector using three value_type components.
Definition vec3f.hpp:45
4D vector using four value_type components.
Definition vec4f.hpp:45
constexpr Vector4F & operator+=(const Vector4F &rhs) noexcept
this = this + rhs, component wise.
Definition vec4f.hpp:169
constexpr Vector4F & operator*=(const Vector4F &s) noexcept
this = this * {s.x, s.y, s.z, s.w}, component wise.
Definition vec4f.hpp:184
constexpr Vector4F & operator/=(const Vector4F &s) noexcept
this = this / {s.x, s.y, s.z, s.w}, component wise.
Definition vec4f.hpp:193
constexpr Vector4F & set(const value_type vx, const value_type vy, const value_type vz, const value_type vw) noexcept
Definition vec4f.hpp:141
constexpr Vector4F & operator*=(const value_type s) noexcept
this = this * s, component wise.
Definition vec4f.hpp:203
Vector3F< value_type, std::is_floating_point_v< value_type > > Vec3
Definition vec4f.hpp:64
constexpr Vector4F & set(const_iterator xyzw) noexcept
this = xyzw, returns this.
Definition vec4f.hpp:145
constexpr_cxx23 bool intersects(const Vector4F &o) const noexcept
Definition vec4f.hpp:276
constexpr Vector4F & mul(const value_type sx, const value_type sy, const value_type sz, const value_type sw) noexcept
this = this * {sx, sy, sz, sw}, component wise.
Definition vec4f.hpp:161
constexpr Vector4F & set(const Vec3f &o, const value_type w_) noexcept
TODO constexpr std::strong_ordering operator<=>(const vec4f_t& rhs) const noexcept { return ....
Definition vec4f.hpp:138
constexpr Vector4F() noexcept
Definition vec4f.hpp:74
constexpr value_type length_sq() const noexcept
Return the squared length of a vector, a.k.a the squared norm or squared magnitude
Definition vec4f.hpp:223
constexpr Vec3 & getVec3(Vec3 &out) const noexcept
out = { this.x, this.y, this.z } dropping w, returns out.
Definition vec4f.hpp:122
constexpr value_type length() const noexcept
Return the length of a vector, a.k.a the norm or magnitude
Definition vec4f.hpp:230
constexpr bool is_zero() const noexcept
Definition vec4f.hpp:216
constexpr value_type operator[](size_t i) const noexcept
Returns read-only component.
Definition vec4f.hpp:100
constexpr Vector4F & add(const value_type dx, const value_type dy, const value_type dz, const value_type dw) noexcept
this = this + {dx, dy, dz, dw}, component wise.
Definition vec4f.hpp:153
constexpr Vector4F(const_iterator v) noexcept
Definition vec4f.hpp:86
constexpr value_type dist(const Vector4F &o) const noexcept
Return the distance between this vector and the given one.
Definition vec4f.hpp:272
constexpr Vector4F & mul(const Vector4F &s) noexcept
this = this * {s.x, s.y, s.z}, component wise.
Definition vec4f.hpp:157
constexpr const_iterator cbegin() const noexcept
Definition vec4f.hpp:106
constexpr Vector4F & normalize() noexcept
Normalize this vector in place.
Definition vec4f.hpp:237
constexpr Vector4F(const value_type x_, const value_type y_, const value_type z_, const value_type w_) noexcept
Definition vec4f.hpp:80
constexpr Vector4F(std::initializer_list< value_type > v) noexcept
Definition vec4f.hpp:89
constexpr Vector4F(Vector4F &&o) noexcept=default
constexpr iterator get(iterator xyzw) const noexcept
xyzw = this, returns xyzw.
Definition vec4f.hpp:118
constexpr Vector4F & add(const Vector4F &d) noexcept
this = this + {d.x, d.y, d.z, d.w}, component wise.
Definition vec4f.hpp:149
constexpr Vector4F(const value_type v) noexcept
Definition vec4f.hpp:77
constexpr Vector4F & scale(const value_type s) noexcept
this = this * s, component wise.
Definition vec4f.hpp:165
constexpr Vector4F(const Vector4F &o) noexcept=default
constexpr Vector4F & operator=(const Vector4F &) noexcept=default
constexpr Vector4F & operator=(Vector4F &&) noexcept=default
std::string toString() const noexcept
Definition vec4f.hpp:214
constexpr Vector4F(const Vec3 &o3, const value_type w_) noexcept
Definition vec4f.hpp:83
constexpr iterator begin() noexcept
Definition vec4f.hpp:115
constexpr bool operator==(const Vector4F &rhs) const noexcept
Definition vec4f.hpp:125
constexpr value_type dist_sq(const Vector4F &o) const noexcept
Return the squared distance between this vector and the given one.
Definition vec4f.hpp:261
constexpr reference operator[](size_t i) noexcept
Returns writeable reference to component.
Definition vec4f.hpp:109
constexpr Vector4F & operator-=(const Vector4F &rhs) noexcept
this = this - rhs, component wise.
Definition vec4f.hpp:175
constexpr Vector4F & operator/=(const value_type s) noexcept
this = this / s, component wise.
Definition vec4f.hpp:211
#define constexpr_cxx23
std::enable_if_t< std::is_floating_point_v< T >, bool > constexpr is_zero(const T &a, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if the given value is less than epsilon, w/ epsilon > 0.
constexpr Vector3F< T > to_vec3(const Vector4F< T > &v) noexcept
out = { this.x, this.y, this.z } dropping w, returns out.
Definition vec4f.hpp:359
constexpr Quaternion< T > operator-(const Quaternion< T > &lhs, const Quaternion< T > &rhs) noexcept
constexpr Vector2F< T > operator/(const Vector2F< T > &lhs, const T s) noexcept
Definition vec2f.hpp:378
constexpr Vector2F< T > max(const Vector2F< T > &lhs, const Vector2F< T > &rhs) noexcept
Definition vec2f.hpp:398
constexpr Vector2F< T > min(const Vector2F< T > &lhs, const Vector2F< T > &rhs) noexcept
Definition vec2f.hpp:392
Vector4F< float > Vec4f
Definition vec4f.hpp:375
Point4F< float > Point4f
Definition vec4f.hpp:390
constexpr Matrix4< T > operator*(const Matrix4< T > &lhs, const Matrix4< T > &rhs) noexcept
Definition mat4f.hpp:1906
Vector3F< float > Vec3f
Definition vec3f.hpp:433
constexpr Quaternion< T > operator+(const Quaternion< T > &lhs, const Quaternion< T > &rhs) noexcept
std::ostream & operator<<(std::ostream &out, const Matrix4< T > &v) noexcept
Definition mat4f.hpp:1924
constexpr Vector2F< T > abs(const Vector2F< T > &lhs) noexcept
Definition vec2f.hpp:404
Vector4F< Value_type > Point4F
Point4F alias of Vector4F.
Definition vec4f.hpp:388
uint8_t Value_type