jaulib v1.3.0
Jau Support Library (C++, Java, ..)
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 <cstdint>
30#include <cassert>
31#include <limits>
32#include <string>
33#include <initializer_list>
34#include <iostream>
35
36#include <jau/float_math.hpp>
37#include <jau/math/vec3f.hpp>
38
39namespace jau::math {
40
41 /** \addtogroup Math
42 *
43 * @{
44 */
45
46 /**
47 * 4D vector using four value_type components.
48 */
49 template<typename Value_type,
50 std::enable_if_t<std::is_floating_point_v<Value_type>, bool> = true>
51 class alignas(Value_type) Vector4F {
52 public:
55 typedef const value_type* const_pointer;
59 typedef const value_type* const_iterator;
60
62
63 constexpr static const value_type zero = value_type(0);
64 constexpr static const value_type one = value_type(1);
65
66 /** Number of components */
67 constexpr static const size_t components = 4;
68
69 /** Size in bytes (aligned) */
70 constexpr static const size_t byte_size = components * sizeof(value_type);
71
76
77 constexpr Vector4F() noexcept
78 : x(zero), y(zero), z(zero), w(zero) {}
79
80 constexpr Vector4F(const value_type v) noexcept
81 : x(v), y(v), z(v), w(v) {}
82
83 constexpr Vector4F(const value_type x_, const value_type y_, const value_type z_, const value_type w_) noexcept
84 : x(x_), y(y_), z(z_), w(w_) {}
85
86 constexpr Vector4F(const Vec3& o3, const value_type w_) noexcept
87 : x(o3.x), y(o3.y), z(o3.z), w(w_) {}
88
89 constexpr Vector4F(const_iterator v) noexcept
90 : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
91
92 constexpr Vector4F(std::initializer_list<value_type> v) noexcept
93 : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
94
95 constexpr Vector4F(const Vector4F& o) noexcept = default;
96 constexpr Vector4F(Vector4F&& o) noexcept = default;
97 constexpr Vector4F& operator=(const Vector4F&) noexcept = default;
98 constexpr Vector4F& operator=(Vector4F&&) noexcept = default;
99
100 /** Returns read-only component */
101 constexpr value_type operator[](size_t i) const noexcept {
102 assert(i < 4);
103 return (&x)[i];
104 }
105
106 explicit operator const_pointer() const noexcept { return &x; }
107 constexpr const_iterator cbegin() const noexcept { return &x; }
108
109 /** Returns writeable reference to component */
110 constexpr reference operator[](size_t i) noexcept {
111 assert(i < 4);
112 return (&x)[i];
113 }
114
115 explicit operator pointer() noexcept { return &x; }
116 constexpr iterator begin() noexcept { return &x; }
117
118 /** xyzw = this, returns xyzw. */
119 constexpr iterator get(iterator xyzw) const noexcept {
120 xyzw[0] = x;
121 xyzw[1] = y;
122 xyzw[2] = z;
123 xyzw[3] = w;
124 return xyzw;
125 }
126
127 /** out = { this.x, this.y, this.z } dropping w, returns out. */
128 constexpr Vec3& getVec3(Vec3& out) const noexcept {
129 out.x = x;
130 out.y = y;
131 out.z = z;
132 return out;
133 }
134
135 constexpr bool operator==(const Vector4F& rhs ) const noexcept {
136 if( this == &rhs ) {
137 return true;
138 }
139 return jau::is_zero(x - rhs.x) && jau::is_zero(y - rhs.y) &&
140 jau::is_zero(z - rhs.z) && jau::is_zero(w - rhs.w);
141 }
142 /** TODO
143 constexpr bool operator<=>(const vec4f_t& rhs ) const noexcept {
144 return ...
145 } */
146
147 /** this = { o, w }, returns this. */
148 constexpr Vector4F& set(const Vec3f& o, const value_type w_) noexcept
149 { x = o.x; y = o.y; z = o.z; w = w_; return *this; }
150
151 constexpr Vector4F& set(const value_type vx, const value_type vy, const value_type vz, const value_type vw) noexcept
152 { x=vx; y=vy; z=vz; w=vw; return *this; }
153
154 /** this = xyzw, returns this. */
155 constexpr Vector4F& set(const_iterator xyzw) noexcept
156 { x=xyzw[0]; y=xyzw[1]; z=xyzw[2]; z=xyzw[3]; return *this; }
157
158 /** this = this + {dx, dy, dz, dw}, returns this. */
159 constexpr Vector4F& add(const value_type dx, const value_type dy, const value_type dz, const value_type dw) noexcept
160 { x+=dx; y+=dy; z+=dz; w+=dw; return *this; }
161
162 /** this = this * {sx, sy, sz, sw}, returns this. */
163 constexpr Vector4F& mul(const value_type sx, const value_type sy, const value_type sz, const value_type sw) noexcept
164 { x*=sx; y*=sy; z*=sz; w*=sw; return *this; }
165
166 /** this = this * s, returns this. */
167 constexpr Vector4F& scale(const value_type s) noexcept
168 { x*=s; y*=s; z*=s; w*=s; return *this; }
169
170 /** this = this + rhs, returns this. */
171 constexpr Vector4F& operator+=(const Vector4F& rhs ) noexcept {
172 x+=rhs.x; y+=rhs.y; z+=rhs.z; w+=rhs.w;
173 return *this;
174 }
175
176 /** this = this - rhs, returns this. */
177 constexpr Vector4F& operator-=(const Vector4F& rhs ) noexcept {
178 x-=rhs.x; y-=rhs.y; z-=rhs.z; w-=rhs.w;
179 return *this;
180 }
181
182 /**
183 * Scale this vector with given scale factor
184 * @param s scale factor
185 * @return this instance
186 */
187 constexpr Vector4F& operator*=(const value_type s ) noexcept {
188 x*=s; y*=s; z*=s; w*=s;
189 return *this;
190 }
191
192 /**
193 * Divide this vector with given scale factor
194 * @param s scale factor
195 * @return this instance
196 */
197 constexpr Vector4F& operator/=(const value_type s ) noexcept {
198 x/=s; y/=s; z/=s; w/=s;
199 return *this;
200 }
201
202 std::string toString() const noexcept { return std::to_string(x)+" / "+std::to_string(y)+" / "+std::to_string(z)+" / "+std::to_string(w); }
203
204 constexpr bool is_zero() const noexcept {
205 return jau::is_zero(x) && jau::is_zero(y) && jau::is_zero(z) && jau::is_zero(w);
206 }
207
208 /**
209 * Return the squared length of a vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i>
210 */
211 constexpr value_type length_sq() const noexcept {
212 return x*x + y*y + z*z + w*w;
213 }
214
215 /**
216 * Return the length of a vector, a.k.a the <i>norm</i> or <i>magnitude</i>
217 */
218 constexpr value_type length() const noexcept {
219 return std::sqrt(length_sq());
220 }
221
222 /**
223 * Normalize this vector in place
224 */
225 constexpr Vector4F& normalize() noexcept {
226 const value_type lengthSq = length_sq();
227 if ( jau::is_zero( lengthSq ) ) {
228 x = zero;
229 y = zero;
230 z = zero;
231 w = zero;
232 } else {
233 const value_type invSqr = one / std::sqrt(lengthSq);
234 x *= invSqr;
235 y *= invSqr;
236 z *= invSqr;
237 w *= invSqr;
238 }
239 return *this;
240 }
241
242 /**
243 * Return the squared distance between this vector and the given one.
244 * <p>
245 * When comparing the relative distance between two points it is usually sufficient to compare the squared
246 * distances, thus avoiding an expensive square root operation.
247 * </p>
248 */
249 constexpr value_type dist_sq(const Vector4F& o) const noexcept {
250 const value_type dx = x - o.x;
251 const value_type dy = y - o.y;
252 const value_type dz = z - o.z;
253 const value_type dw = w - o.w;
254 return dx*dx + dy*dy + dz*dz + dw*dw;
255 }
256
257 /**
258 * Return the distance between this vector and the given one.
259 */
260 constexpr value_type dist(const Vector4F& o) const noexcept {
261 return std::sqrt(dist_sq(o));
262 }
263
264 constexpr_cxx23 bool intersects(const Vector4F& o) const noexcept {
265 const value_type eps = std::numeric_limits<value_type>::epsilon();
266 if( std::abs(x-o.x) >= eps || std::abs(y-o.y) >= eps ||
267 std::abs(z-o.z) >= eps || std::abs(w-o.w) >= eps ) {
268 return false;
269 }
270 return true;
271 }
272 };
273
274 template<typename T,
275 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
276 constexpr Vector4F<T> operator+(const Vector4F<T>& lhs, const Vector4F<T>& rhs ) noexcept {
277 // Returning a Vector4 object from the returned reference of operator+=()
278 // may hinder copy-elision or "named return value optimization" (NRVO).
279 // return Vector4<T>(lhs) += rhs;
280
281 // Returning named object allows copy-elision (NRVO),
282 // only one object is created 'on target'.
283 Vector4F<T> r(lhs); r += rhs; return r;
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 Vector4F<T> r(lhs); r -= rhs; return r;
290 }
291
292 template<typename T,
293 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
294 constexpr Vector4F<T> operator*(const Vector4F<T>& lhs, const T s ) noexcept {
295 Vector4F<T> r(lhs); r *= s; 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 T s, const Vector4F<T>& rhs) noexcept {
301 Vector4F<T> r(rhs); r *= s; 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, const T s ) noexcept {
307 Vector4F<T> r(lhs); r /= s; return r;
308 }
309
310 /** out = { this.x, this.y, this.z } dropping w, returns out. */
311 template<typename T,
312 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
313 constexpr Vector3F<T> to_vec3(const Vector4F<T>& v) noexcept {
314 Vector3F<T> r; v.getVec3(r); return r;
315 }
316
317 template<typename T,
318 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
319 std::ostream& operator<<(std::ostream& out, const Vector4F<T>& v) noexcept {
320 return out << v.toString();
321 }
322
324 static_assert(alignof(float) == alignof(Vec4f));
325 static_assert(sizeof(float)*4 == sizeof(Vec4f));
326
327 /**
328 * Point4F alias of Vector4F
329 */
330 template<typename T,
331 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
333
335 static_assert(alignof(float) == alignof(Point4f));
336 static_assert(sizeof(float)*4 == sizeof(Point4f));
337
338 /**@}*/
339
340} // namespace jau::math
341
342#endif /* JAU_VEC4F_HPP_ */
3D vector using three value_type components.
Definition: vec3f.hpp:51
value_type x
Definition: vec3f.hpp:72
4D vector using four value_type components.
Definition: vec4f.hpp:51
value_type w
Definition: vec4f.hpp:75
const value_type & const_reference
Definition: vec4f.hpp:57
constexpr Vector4F & operator+=(const Vector4F &rhs) noexcept
this = this + rhs, returns this.
Definition: vec4f.hpp:171
value_type & reference
Definition: vec4f.hpp:56
constexpr Vector4F & set(const value_type vx, const value_type vy, const value_type vz, const value_type vw) noexcept
Definition: vec4f.hpp:151
constexpr Vector4F & operator*=(const value_type s) noexcept
Scale this vector with given scale factor.
Definition: vec4f.hpp:187
value_type * iterator
Definition: vec4f.hpp:58
value_type * pointer
Definition: vec4f.hpp:54
Vector3F< value_type, std::is_floating_point_v< Value_type > > Vec3
Definition: vec4f.hpp:61
constexpr Vector4F & set(const_iterator xyzw) noexcept
this = xyzw, returns this.
Definition: vec4f.hpp:155
constexpr_cxx23 bool intersects(const Vector4F &o) const noexcept
Definition: vec4f.hpp:264
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:163
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:148
constexpr Vector4F() noexcept
Definition: vec4f.hpp:77
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:211
const value_type * const_iterator
Definition: vec4f.hpp:59
constexpr Vec3 & getVec3(Vec3 &out) const noexcept
out = { this.x, this.y, this.z } dropping w, returns out.
Definition: vec4f.hpp:128
constexpr value_type length() const noexcept
Return the length of a vector, a.k.a the norm or magnitude
Definition: vec4f.hpp:218
constexpr bool is_zero() const noexcept
Definition: vec4f.hpp:204
Value_type value_type
Definition: vec4f.hpp:53
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:159
constexpr Vector4F(const_iterator v) noexcept
Definition: vec4f.hpp:89
const value_type * const_pointer
Definition: vec4f.hpp:55
value_type x
Definition: vec4f.hpp:72
constexpr value_type dist(const Vector4F &o) const noexcept
Return the distance between this vector and the given one.
Definition: vec4f.hpp:260
value_type y
Definition: vec4f.hpp:73
constexpr const_iterator cbegin() const noexcept
Definition: vec4f.hpp:107
constexpr Vector4F & normalize() noexcept
Normalize this vector in place.
Definition: vec4f.hpp:225
constexpr Vector4F(const value_type x_, const value_type y_, const value_type z_, const value_type w_) noexcept
Definition: vec4f.hpp:83
constexpr Vector4F(std::initializer_list< value_type > v) noexcept
Definition: vec4f.hpp:92
constexpr Vector4F(Vector4F &&o) noexcept=default
constexpr iterator get(iterator xyzw) const noexcept
xyzw = this, returns xyzw.
Definition: vec4f.hpp:119
constexpr Vector4F(const value_type v) noexcept
Definition: vec4f.hpp:80
value_type z
Definition: vec4f.hpp:74
constexpr Vector4F & scale(const value_type s) noexcept
this = this * s, returns this.
Definition: vec4f.hpp:167
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:202
constexpr Vector4F(const Vec3 &o3, const value_type w_) noexcept
Definition: vec4f.hpp:86
constexpr iterator begin() noexcept
Definition: vec4f.hpp:116
constexpr bool operator==(const Vector4F &rhs) const noexcept
Definition: vec4f.hpp:135
constexpr value_type dist_sq(const Vector4F &o) const noexcept
Return the squared distance between this vector and the given one.
Definition: vec4f.hpp:249
constexpr reference operator[](size_t i) noexcept
Returns writeable reference to component.
Definition: vec4f.hpp:110
constexpr Vector4F & operator-=(const Vector4F &rhs) noexcept
this = this - rhs, returns this.
Definition: vec4f.hpp:177
constexpr Vector4F & operator/=(const value_type s) noexcept
Divide this vector with given scale factor.
Definition: vec4f.hpp:197
std::string to_string(const alphabet &v) noexcept
Definition: base_codec.hpp:97
#define constexpr_cxx23
std::enable_if< std::is_floating_point_v< T >, bool >::type 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.
Definition: float_math.hpp:255
constexpr T abs(const T x) noexcept
Returns the absolute value of an arithmetic number (w/ branching) in O(1)
Definition: base_math.hpp:155
constexpr Vector3F< T > to_vec3(const Vector4F< T > &v) noexcept
out = { this.x, this.y, this.z } dropping w, returns out.
Definition: vec4f.hpp:313
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:346
Vector4F< float > Vec4f
Definition: vec4f.hpp:323
Point4F< float > Point4f
Definition: vec4f.hpp:334
constexpr Matrix4< T > operator*(const Matrix4< T > &lhs, const Matrix4< T > &rhs) noexcept
Definition: mat4f.hpp:1859
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:1877
constexpr const jau::fraction_i64 zero(0l, 1lu)
zero is 0/1
constexpr const jau::fraction_i64 one(1l, 1lu)
one is 10^0 or 1/1
uint8_t Value_type