jaulib v1.3.6
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 (c) 2022-2024 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24#ifndef JAU_VEC4F_HPP_
25#define JAU_VEC4F_HPP_
26
27#include <cmath>
28#include <cstdarg>
29#include <cassert>
30#include <limits>
31#include <string>
32#include <algorithm>
33#include <initializer_list>
34
35#include <jau/float_math.hpp>
36
37#include <iostream>
38
39#include <jau/math/vec3f.hpp>
40
41namespace jau::math {
42
43 /** \addtogroup Math
44 *
45 * @{
46 */
47
48 /**
49 * 4D vector using four value_type components.
50 *
51 * Component and overall alignment is natural as sizeof(value_type),
52 * i.e. sizeof(value_type) == alignof(value_type)
53 */
54 template <typename Value_type,
55 std::enable_if_t<std::is_floating_point_v<Value_type> &&
56 sizeof(Value_type) == alignof(Value_type), bool> = true>
57 class alignas(sizeof(Value_type)) Vector4F {
58 public:
61 typedef const value_type* const_pointer;
65 typedef const value_type* const_iterator;
66
67 /** value alignment is sizeof(value_type) */
68 constexpr static int value_alignment = sizeof(value_type);
69
70 /** Number of value_type components */
71 constexpr static const size_t components = 4;
72
73 /** Size in bytes with value_alignment */
74 constexpr static const size_t byte_size = components * sizeof(value_type);
75
77
78 constexpr static const value_type zero = value_type(0);
79 constexpr static const value_type one = value_type(1);
80
85
86 constexpr Vector4F() noexcept
87 : x(zero), y(zero), z(zero), w(zero) {}
88
89 constexpr Vector4F(const value_type v) noexcept
90 : x(v), y(v), z(v), w(v) {}
91
92 constexpr Vector4F(const value_type x_, const value_type y_, const value_type z_, const value_type w_) noexcept
93 : x(x_), y(y_), z(z_), w(w_) {}
94
95 constexpr Vector4F(const Vec3& o3, const value_type w_) noexcept
96 : x(o3.x), y(o3.y), z(o3.z), w(w_) {}
97
98 constexpr Vector4F(const_iterator v) noexcept
99 : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
100
101 constexpr Vector4F(std::initializer_list<value_type> v) noexcept
102 : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
103
104 constexpr Vector4F(const Vector4F& o) noexcept = default;
105 constexpr Vector4F(Vector4F&& o) noexcept = default;
106 constexpr Vector4F& operator=(const Vector4F&) noexcept = default;
107 constexpr Vector4F& operator=(Vector4F&&) noexcept = default;
108
109 constexpr Vector4F copy() noexcept { return Vector4F(*this); }
110
111 /** Returns read-only component */
112 constexpr value_type operator[](size_t i) const noexcept {
113 assert(i < 4);
114 return (&x)[i];
115 }
116
117 explicit operator const_pointer() const noexcept { return &x; }
118 constexpr const_iterator cbegin() const noexcept { return &x; }
119
120 /** Returns writeable reference to component */
121 constexpr reference operator[](size_t i) noexcept {
122 assert(i < 4);
123 return (&x)[i];
124 }
125
126 explicit operator pointer() noexcept { return &x; }
127 constexpr iterator begin() noexcept { return &x; }
128
129 /** xyzw = this, returns xyzw. */
130 constexpr iterator get(iterator xyzw) const noexcept
131 { xyzw[0] = x; xyzw[1] = y; xyzw[2] = z; xyzw[3] = w; return xyzw; }
132
133 /** out = { this.x, this.y, this.z } dropping w, returns out. */
134 constexpr Vec3& getVec3(Vec3& out) const noexcept
135 { out.x = x; out.y = y; out.z = z; return out; }
136
137 constexpr bool operator==(const Vector4F& rhs) const noexcept {
138 if (this == &rhs) {
139 return true;
140 }
141 return jau::is_zero(x - rhs.x) && jau::is_zero(y - rhs.y) &&
142 jau::is_zero(z - rhs.z) && jau::is_zero(w - rhs.w);
143 }
144 /** TODO
145 constexpr bool operator<=>(const vec4f_t& rhs ) const noexcept {
146 return ...
147 } */
148
149 /** this = { o, w }, returns this. */
150 constexpr Vector4F& set(const Vec3f& o, const value_type w_) noexcept
151 { x = o.x; y = o.y; z = o.z; w = w_; return *this; }
152
153 constexpr Vector4F& set(const value_type vx, const value_type vy, const value_type vz, const value_type vw) noexcept
154 { x=vx; y=vy; z=vz; w=vw; return *this; }
155
156 /** this = xyzw, returns this. */
157 constexpr Vector4F& set(const_iterator xyzw) noexcept
158 { x=xyzw[0]; y=xyzw[1]; z=xyzw[2]; z=xyzw[3]; return *this; }
159
160 /** this = this + {dx, dy, dz, dw}, returns this. */
161 constexpr Vector4F& add(const value_type dx, const value_type dy, const value_type dz, const value_type dw) noexcept
162 { x+=dx; y+=dy; z+=dz; w+=dw; return *this; }
163
164 /** this = this * {sx, sy, sz, sw}, returns this. */
165 constexpr Vector4F& mul(const value_type sx, const value_type sy, const value_type sz, const value_type sw) noexcept
166 { x*=sx; y*=sy; z*=sz; w*=sw; return *this; }
167
168 /** this = this * s, returns this. */
169 constexpr Vector4F& scale(const value_type s) noexcept
170 { x*=s; y*=s; z*=s; w*=s; return *this; }
171
172 /** this = this + rhs, returns this. */
173 constexpr Vector4F& operator+=(const Vector4F& rhs ) noexcept {
174 x+=rhs.x; y+=rhs.y; z+=rhs.z; w+=rhs.w;
175 return *this;
176 }
177
178 /** this = this - rhs, returns this. */
179 constexpr Vector4F& operator-=(const Vector4F& rhs ) noexcept
180 { x-=rhs.x; y-=rhs.y; z-=rhs.z; w-=rhs.w; return *this;
181 }
182
183 /**
184 * Scale this vector with given scale factor
185 * @param s scale factor
186 * @return this instance
187 */
188 constexpr Vector4F& operator*=(const value_type s ) noexcept
189 { x*=s; y*=s; z*=s; w*=s; return *this; }
190
191 /**
192 * Divide this vector with given scale factor
193 * @param s scale factor
194 * @return this instance
195 */
196 constexpr Vector4F& operator/=(const value_type s ) noexcept
197 { x/=s; y/=s; z/=s; w/=s; return *this; }
198
199 std::string toString() const noexcept { return std::to_string(x) + ", " + std::to_string(y) + ", " + std::to_string(z) + ", " + std::to_string(w); }
200
201 constexpr bool is_zero() const noexcept {
203 }
204
205 /**
206 * Return the squared length of a vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i>
207 */
208 constexpr value_type length_sq() const noexcept {
209 return x*x + y*y + z*z + w*w;
210 }
211
212 /**
213 * Return the length of a vector, a.k.a the <i>norm</i> or <i>magnitude</i>
214 */
215 constexpr value_type length() const noexcept {
216 return std::sqrt(length_sq());
217 }
218
219 /**
220 * Normalize this vector in place
221 */
222 constexpr Vector4F& normalize() noexcept {
223 const value_type lengthSq = length_sq();
224 if (jau::is_zero(lengthSq)) {
225 x = zero;
226 y = zero;
227 z = zero;
228 w = zero;
229 } else {
230 const value_type invSqr = one / std::sqrt(lengthSq);
231 x *= invSqr;
232 y *= invSqr;
233 z *= invSqr;
234 w *= invSqr;
235 }
236 return *this;
237 }
238
239 /**
240 * Return the squared distance between this vector and the given one.
241 * <p>
242 * When comparing the relative distance between two points it is usually sufficient to compare the squared
243 * distances, thus avoiding an expensive square root operation.
244 * </p>
245 */
246 constexpr value_type dist_sq(const Vector4F& o) const noexcept {
247 const value_type dx = x - o.x;
248 const value_type dy = y - o.y;
249 const value_type dz = z - o.z;
250 const value_type dw = w - o.w;
251 return dx*dx + dy*dy + dz*dz + dw*dw;
252 }
253
254 /**
255 * Return the distance between this vector and the given one.
256 */
257 constexpr value_type dist(const Vector4F& o) const noexcept {
258 return std::sqrt(dist_sq(o));
259 }
260
261 constexpr_cxx23 bool intersects(const Vector4F& o) const noexcept {
262 const value_type eps = std::numeric_limits<value_type>::epsilon();
263 if (std::abs(x - o.x) >= eps || std::abs(y - o.y) >= eps ||
264 std::abs(z - o.z) >= eps || std::abs(w - o.w) >= eps) {
265 return false;
266 }
267 return true;
268 }
269 };
270
271 template <typename T,
272 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
273 constexpr Vector4F<T> operator+(const Vector4F<T>& lhs, const Vector4F<T>& rhs) noexcept {
274 // Returning a Vector4 object from the returned reference of operator+=()
275 // may hinder copy-elision or "named return value optimization" (NRVO).
276 // return Vector4<T>(lhs) += rhs;
277
278 // Returning named object allows copy-elision (NRVO),
279 // only one object is created 'on target'.
280 Vector4F<T> r(lhs); r += rhs; return r;
281 }
282
283 template<typename T,
284 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
285 constexpr Vector4F<T> operator-(const Vector4F<T>& lhs, const Vector4F<T>& rhs ) noexcept {
286 Vector4F<T> r(lhs); r -= rhs; return r;
287 }
288
289 template<typename T,
290 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
291 constexpr Vector4F<T> operator-(const Vector4F<T>& lhs) noexcept {
292 Vector4F<T> r(lhs);
293 r *= -1;
294 return r;
295 }
296
297 template<typename T,
298 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
299 constexpr Vector4F<T> operator*(const Vector4F<T>& lhs, const T s ) noexcept {
300 Vector4F<T> r(lhs); r *= s; return r;
301 }
302
303 template<typename T,
304 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
305 constexpr Vector4F<T> operator*(const T s, const Vector4F<T>& rhs) noexcept {
306 Vector4F<T> r(rhs); r *= s; return r;
307 }
308
309 template<typename T,
310 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
311 constexpr Vector4F<T> operator/(const Vector4F<T>& lhs, const T s ) noexcept {
312 Vector4F<T> r(lhs); r /= s; return r;
313 }
314
315 template<typename T,
316 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
317 constexpr Vector4F<T> min(const Vector4F<T>& lhs, const Vector4F<T>& rhs) noexcept {
318 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));
319 }
320
321 template<typename T,
322 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
323 constexpr Vector4F<T> max(const Vector4F<T>& lhs, const Vector4F<T>& rhs) noexcept {
324 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));
325 }
326
327 /** out = { this.x, this.y, this.z } dropping w, returns out. */
328 template<typename T,
329 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
330 constexpr Vector3F<T> to_vec3(const Vector4F<T>& v) noexcept {
331 Vector3F<T> r; v.getVec3(r); return r;
332 }
333
334 template <typename T,
335 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
336 std::ostream& operator<<(std::ostream& out, const Vector4F<T>& v) noexcept {
337 return out << v.toString();
338 }
339
340 static_assert(4 == Vector4F<double>::components);
341 static_assert(sizeof(double) == Vector4F<double>::value_alignment);
342 static_assert(sizeof(double) == alignof(Vector4F<double>));
343 static_assert(sizeof(double) * 4 == Vector4F<double>::byte_size);
344 static_assert(sizeof(double) * 4 == sizeof(Vector4F<double>));
345
347 static_assert(4 == Vec4f::components);
348 static_assert(sizeof(float) == Vec4f::value_alignment);
349 static_assert(sizeof(float) == alignof(Vec4f));
350 static_assert(sizeof(float) * 4 == Vec4f::byte_size);
351 static_assert(sizeof(float) * 4 == sizeof(Vec4f));
352
353 /**
354 * Point4F alias of Vector4F
355 */
356 template <typename Value_type,
357 std::enable_if_t<std::is_floating_point_v<Value_type> &&
358 sizeof(Value_type) == alignof(Value_type), bool> = true>
360
362 static_assert(4 == Point4f::components);
363 static_assert(sizeof(float) == Point4f::value_alignment);
364 static_assert(sizeof(float) == alignof(Point4f));
365 static_assert(sizeof(float) * 4 == Point4f::byte_size);
366 static_assert(sizeof(float) * 4 == sizeof(Point4f));
367
368 /**@}*/
369
370} // namespace jau::math
371
372#endif /* JAU_VEC4F_HPP_ */
3D vector using three value_type components.
Definition vec3f.hpp:57
4D vector using four value_type components.
Definition vec4f.hpp:57
constexpr Vector4F & operator+=(const Vector4F &rhs) noexcept
this = this + rhs, returns this.
Definition vec4f.hpp:173
constexpr Vector4F & set(const value_type vx, const value_type vy, const value_type vz, const value_type vw) noexcept
Definition vec4f.hpp:153
constexpr Vector4F & operator*=(const value_type s) noexcept
Scale this vector with given scale factor.
Definition vec4f.hpp:188
Vector3F< value_type, std::is_floating_point_v< value_type > > Vec3
Definition vec4f.hpp:76
constexpr Vector4F & set(const_iterator xyzw) noexcept
this = xyzw, returns this.
Definition vec4f.hpp:157
constexpr_cxx23 bool intersects(const Vector4F &o) const noexcept
Definition vec4f.hpp:261
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}, returns this.
Definition vec4f.hpp:165
constexpr Vector4F & set(const Vec3f &o, const value_type w_) noexcept
TODO constexpr bool operator<=>(const vec4f_t& rhs ) const noexcept { return ... }...
Definition vec4f.hpp:150
constexpr Vector4F() noexcept
Definition vec4f.hpp:86
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:208
constexpr Vec3 & getVec3(Vec3 &out) const noexcept
out = { this.x, this.y, this.z } dropping w, returns out.
Definition vec4f.hpp:134
constexpr value_type length() const noexcept
Return the length of a vector, a.k.a the norm or magnitude
Definition vec4f.hpp:215
constexpr bool is_zero() const noexcept
Definition vec4f.hpp:201
constexpr value_type operator[](size_t i) const noexcept
Returns read-only component.
Definition vec4f.hpp:112
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}, returns this.
Definition vec4f.hpp:161
constexpr Vector4F(const_iterator v) noexcept
Definition vec4f.hpp:98
constexpr value_type dist(const Vector4F &o) const noexcept
Return the distance between this vector and the given one.
Definition vec4f.hpp:257
constexpr const_iterator cbegin() const noexcept
Definition vec4f.hpp:118
constexpr Vector4F & normalize() noexcept
Normalize this vector in place.
Definition vec4f.hpp:222
constexpr Vector4F(const value_type x_, const value_type y_, const value_type z_, const value_type w_) noexcept
Definition vec4f.hpp:92
constexpr Vector4F(std::initializer_list< value_type > v) noexcept
Definition vec4f.hpp:101
constexpr Vector4F(Vector4F &&o) noexcept=default
constexpr iterator get(iterator xyzw) const noexcept
xyzw = this, returns xyzw.
Definition vec4f.hpp:130
constexpr Vector4F(const value_type v) noexcept
Definition vec4f.hpp:89
constexpr Vector4F & scale(const value_type s) noexcept
this = this * s, returns this.
Definition vec4f.hpp:169
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:199
constexpr Vector4F(const Vec3 &o3, const value_type w_) noexcept
Definition vec4f.hpp:95
constexpr iterator begin() noexcept
Definition vec4f.hpp:127
constexpr bool operator==(const Vector4F &rhs) const noexcept
Definition vec4f.hpp:137
constexpr value_type dist_sq(const Vector4F &o) const noexcept
Return the squared distance between this vector and the given one.
Definition vec4f.hpp:246
constexpr reference operator[](size_t i) noexcept
Returns writeable reference to component.
Definition vec4f.hpp:121
constexpr Vector4F & operator-=(const Vector4F &rhs) noexcept
this = this - rhs, returns this.
Definition vec4f.hpp:179
constexpr Vector4F & operator/=(const value_type s) noexcept
Divide this vector with given scale factor.
Definition vec4f.hpp:196
#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:330
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:363
constexpr Vector2F< T > max(const Vector2F< T > &lhs, const Vector2F< T > &rhs) noexcept
Definition vec2f.hpp:375
constexpr Vector2F< T > min(const Vector2F< T > &lhs, const Vector2F< T > &rhs) noexcept
Definition vec2f.hpp:369
Vector4F< float > Vec4f
Definition vec4f.hpp:346
Point4F< float > Point4f
Definition vec4f.hpp:361
constexpr Matrix4< T > operator*(const Matrix4< T > &lhs, const Matrix4< T > &rhs) noexcept
Definition mat4f.hpp:1863
Vector3F< float > Vec3f
Definition vec3f.hpp:404
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:1881
Vector4F< Value_type > Point4F
Point4F alias of Vector4F.
Definition vec4f.hpp:359
uint8_t Value_type