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