jaulib v1.3.8
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
vec2i.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_VEC2I_HPP_
13#define JAU_MATH_VEC2I_HPP_
14
15#include <cmath>
16#include <cstdarg>
17#include <cassert>
18#include <limits>
19#include <string>
20#include <algorithm>
21#include <iostream>
22
23#include <jau/float_math.hpp>
24
25namespace jau::math {
26
27 /** \addtogroup Math
28 *
29 * @{
30 */
31
32 /**
33 * 2D vector using two value_type components.
34 *
35 * Component and overall alignment is natural as sizeof(value_type),
36 * i.e. sizeof(value_type) == alignof(value_type)
37 */
38 template<typename Value_type,
39 std::enable_if_t<std::is_integral_v<Value_type> &&
40 sizeof(Value_type) == alignof(Value_type), bool> = true>
41 class alignas(sizeof(Value_type)) Vector2I {
42 public:
45 typedef const value_type* const_pointer;
49 typedef const value_type* const_iterator;
50
51 /** value alignment is sizeof(value_type) */
52 constexpr static int value_alignment = sizeof(value_type);
53
54 /** Number of value_type components */
55 constexpr static const size_t components = 2;
56
57 /** Size in bytes with value_alignment */
58 constexpr static const size_t byte_size = components * sizeof(value_type);
59
60 typedef typename jau::float_bytes<sizeof(value_type)>::type float_type;
61
62 constexpr static const value_type zero = value_type(0);
63 constexpr static const value_type one = value_type(1);
64
67
68 constexpr Vector2I() noexcept
69 : x(zero), y(zero) {}
70
71 constexpr Vector2I(const value_type v) noexcept
72 : x(v), y(v) {}
73
74 constexpr Vector2I(const value_type x_, const value_type y_) noexcept
75 : x(x_), y(y_) {}
76
77 constexpr Vector2I(const Vector2I& o) noexcept = default;
78 constexpr Vector2I(Vector2I&& o) noexcept = default;
79 constexpr Vector2I& operator=(const Vector2I&) noexcept = default;
80 constexpr Vector2I& operator=(Vector2I&&) noexcept = default;
81
82 constexpr Vector2I copy() noexcept { return Vector2I(*this); }
83
84 /** Returns read-only component */
85 constexpr value_type operator[](size_t i) const noexcept {
86 assert(i < 2);
87 return (&x)[i];
88 }
89
90 explicit operator const_pointer() const noexcept { return &x; }
91 constexpr const_iterator cbegin() const noexcept { return &x; }
92
93 /** Returns writeable reference to component */
94 constexpr reference operator[](size_t i) noexcept {
95 assert(i < 2);
96 return (&x)[i];
97 }
98
99 explicit operator pointer() noexcept { return &x; }
100 constexpr iterator begin() noexcept { return &x; }
101
102 /** xy = this, returns xy. */
103 constexpr iterator get(iterator xy) const noexcept {
104 xy[0] = x;
105 xy[1] = y;
106 return xy;
107 }
108
109 constexpr bool operator==(const Vector2I& rhs ) const noexcept {
110 if( this == &rhs ) {
111 return true;
112 }
113 return x == rhs.x && y == rhs.y;
114 }
115 /** TODO
116 constexpr bool operator<=>(const vec2i_t& rhs ) const noexcept {
117 return ...
118 } */
119
120 constexpr Vector2I& set(const value_type vx, const value_type vy) noexcept
121 { x=vx; y=vy; return *this; }
122
123 /** this = xy, returns this. */
124 constexpr Vector2I& set(const_iterator xy) noexcept
125 { x=xy[0]; y=xy[1]; return *this; }
126
127 /** this = this + {d.x, d.y}, component wise. Returns this. */
128 constexpr Vector2I& add(const Vector2I& d) noexcept
129 { x+=d.x; y+=d.y; return *this; }
130
131 /** this = this + {sx, sy}, component wise. Returns this. */
132 constexpr Vector2I& add(const value_type dx, const value_type dy) noexcept
133 { x+=dx; y+=dy; return *this; }
134
135 /** this = this * {s.x, s.y}, component wise. Returns this. */
136 constexpr Vector2I& mul(const Vector2I& s) noexcept
137 { x*=s.x; y*=s.y; return *this; }
138
139 /** this = this * {sx, sy}, component wise. Returns this. */
140 constexpr Vector2I& mul(const value_type sx, const value_type sy) noexcept
141 { x*=sx; y*=sy; return *this; }
142
143 /** this = this * s, component wise. Returns this. */
144 constexpr Vector2I& scale(const value_type s) noexcept
145 { x*=s; y*=s; return *this; }
146
147 /** this = this + rhs, component wise. Returns this. */
148 constexpr Vector2I& operator+=(const Vector2I& rhs ) noexcept {
149 x+=rhs.x; y+=rhs.y;
150 return *this;
151 }
152
153 /** this = this - rhs, component wise. Returns this. */
154 constexpr Vector2I& operator-=(const Vector2I& rhs ) noexcept {
155 x-=rhs.x; y-=rhs.y;
156 return *this;
157 }
158
159 /**
160 * this = this * {s.x, s.y}, component wise.
161 * @param s scale factor
162 * @return this instance
163 */
164 constexpr Vector2I& operator*=(const Vector2I& s) noexcept {
165 x*=s.x; y*=s.y;
166 return *this;
167 }
168 /**
169 * this = this / {s.x, s.y}, component wise.
170 * @param s scale factor
171 * @return this instance
172 */
173 constexpr Vector2I& operator/=(const Vector2I& s) noexcept {
174 x/=s.x; y/=s.y;
175 return *this;
176 }
177
178 /**
179 * this = this * s, component wise.
180 * @param s scale factor
181 * @return this instance
182 */
183 constexpr Vector2I& operator*=(const value_type s ) noexcept {
184 x*=s; y*=s;
185 return *this;
186 }
187
188 /**
189 * this = this * s, component wise.
190 * @param s scale factor
191 * @return this instance
192 */
193 constexpr Vector2I& operator/=(const value_type s ) noexcept {
194 x/=s; y/=s;
195 return *this;
196 }
197
198 constexpr_cxx26 void rotate(const float_type radians, const Vector2I& ctr) {
199 const float_type cos = std::cos(radians);
200 const float_type sin = std::sin(radians);
201 rotate(sin, cos, ctr);
202 }
203 void rotate(const float_type sin, const float_type cos, const Vector2I& ctr) {
204 const float_type x0 = static_cast<float_type>(x - ctr.x);
205 const float_type y0 = static_cast<float_type>(y - ctr.y);
206 const value_type tmp = jau::round_to_int<float_type>( x0 * cos - y0 * sin ) + ctr.x;
207 y = jau::round_to_int<float_type>( x0 * sin + y0 * cos ) + ctr.y;
208 x = tmp;
209 }
210
211 std::string toString() const noexcept { return std::to_string(x)+", "+std::to_string(y); }
212
213 constexpr bool is_zero() const noexcept {
214 return jau::is_zero(x) && jau::is_zero(y);
215 }
216
217 /**
218 * Return the squared length of this 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;
222 }
223
224 /**
225 * Return the length of this vector, a.k.a the <i>norm</i> or <i>magnitude</i>
226 */
227 constexpr value_type length() const noexcept {
228 // return jau::round_to_int<float_type>( std::sqrt<float_type>( length_sq() ) );
229 return jau::round_to_int<float_type>( std::sqrt( static_cast<float_type> ( length_sq() )) );
230 }
231
232 /** Normalize this vector in place, returns *this */
233 constexpr Vector2I& normalize() noexcept {
234 const value_type lengthSq = length_sq();
235 if ( jau::is_zero( lengthSq ) ) {
236 x = zero;
237 y = zero;
238 } else {
239 const float_type invSqr = one / static_cast<float_type>( std::sqrt(lengthSq) );
240 x = jau::round_to_int<float_type>( x * invSqr );
241 y = jau::round_to_int<float_type>( x * invSqr );
242 }
243 return *this;
244 }
245
246
247 bool intersects(const Vector2I& o) {
248 return x == o.x && y == o.y;
249 }
250 };
251
252 template<typename T,
253 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
254 constexpr Vector2I<T> operator+(const Vector2I<T>& lhs, const Vector2I<T>& rhs ) noexcept {
255 // Returning a Vector2I<T> object from the returned reference of operator+=()
256 // may hinder copy-elision or "named return value optimization" (NRVO).
257 // return Vector2I<T>(lhs) += rhs;
258
259 // Returning named object allows copy-elision (NRVO),
260 // only one object is created 'on target'.
261 Vector2I<T> r(lhs); r += rhs; return r;
262 }
263
264 template<typename T,
265 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
266 constexpr Vector2I<T> operator-(const Vector2I<T>& lhs, const Vector2I<T>& rhs ) noexcept {
267 Vector2I<T> r(lhs); r -= rhs; return r;
268 }
269
270 template<typename T,
271 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
272 constexpr Vector2I<T> operator-(const Vector2I<T>& lhs) noexcept {
273 Vector2I<T> r(lhs);
274 r *= -1;
275 return r;
276 }
277
278 template<typename T,
279 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
280 constexpr Vector2I<T> operator*(const Vector2I<T>& lhs, const float s ) noexcept {
281 Vector2I<T> r(lhs); r *= s; return r;
282 }
283
284 template<typename T,
285 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
286 constexpr Vector2I<T> operator*(const float s, const Vector2I<T>& rhs) noexcept {
287 Vector2I<T> r(rhs); r *= s; return r;
288 }
289
290 template<typename T,
291 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
292 constexpr Vector2I<T> operator/(const Vector2I<T>& lhs, const float s ) noexcept {
293 Vector2I<T> r(lhs); r /= s; return r;
294 }
295
296 template<typename T,
297 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
298 constexpr Vector2I<T> operator/(const T s, const Vector2I<T>& rhs) noexcept {
299 Vector2I<T> r(rhs);
300 r.x=s/r.x; r.y=s/r.y;
301 return r;
302 }
303
304 template<typename T,
305 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
306 constexpr Vector2I<T> min(const Vector2I<T>& lhs, const Vector2I<T>& rhs) noexcept {
307 return Vector2I<T>(std::min(lhs.x, rhs.x), std::min(lhs.y, rhs.y));
308 }
309
310 template<typename T,
311 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
312 constexpr Vector2I<T> max(const Vector2I<T>& lhs, const Vector2I<T>& rhs) noexcept {
313 return Vector2I<T>(std::max(lhs.x, rhs.x), std::max(lhs.y, rhs.y));
314 }
315
316 template<typename T,
317 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
318 constexpr Vector2I<T> abs(const Vector2I<T>& lhs) noexcept {
319 return Vector2I<T>(std::abs(lhs.x), std::abs(lhs.y));
320 }
321
322 template<typename T,
323 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
324 std::ostream& operator<<(std::ostream& out, const Vector2I<T>& v) noexcept {
325 return out << v.toString();
326 }
327
329 static_assert(2 == Vec2i::components);
330 static_assert(sizeof(int) == Vec2i::value_alignment);
331 static_assert(sizeof(int) == alignof(Vec2i));
332 static_assert(sizeof(int)*2 == Vec2i::byte_size);
333 static_assert(sizeof(int)*2 == sizeof(Vec2i));
334
335 /**
336 * Point2I alias of Vector2I
337 */
338 template<typename Value_type,
339 std::enable_if_t<std::numeric_limits<Value_type>::is_integer &&
340 sizeof(Value_type) == alignof(Value_type), bool> = true>
342
344 static_assert(2 == Point2i::components);
345 static_assert(sizeof(int) == Point2i::value_alignment);
346 static_assert(sizeof(int) == alignof(Point2i));
347 static_assert(sizeof(int)*2 == Point2i::byte_size);
348 static_assert(sizeof(int)*2 == sizeof(Point2i));
349
350 /**@}*/
351
352} // namespace jau::math
353
354#endif /* JAU_MATH_VEC2I_HPP_ */
355
2D vector using two value_type components.
Definition vec2i.hpp:41
constexpr Vector2I & operator-=(const Vector2I &rhs) noexcept
this = this - rhs, component wise.
Definition vec2i.hpp:154
constexpr Vector2I(const Vector2I &o) noexcept=default
static constexpr const value_type zero
Definition vec2i.hpp:62
constexpr Vector2I & add(const Vector2I &d) noexcept
this = this + {d.x, d.y}, component wise.
Definition vec2i.hpp:128
constexpr Vector2I(Vector2I &&o) noexcept=default
constexpr Vector2I & mul(const Vector2I &s) noexcept
this = this * {s.x, s.y}, component wise.
Definition vec2i.hpp:136
constexpr iterator get(iterator xy) const noexcept
xy = this, returns xy.
Definition vec2i.hpp:103
value_type * iterator
Definition vec2i.hpp:48
const value_type * const_pointer
Definition vec2i.hpp:45
constexpr Vector2I() noexcept
Definition vec2i.hpp:68
constexpr value_type length_sq() const noexcept
Return the squared length of this vector, a.k.a the squared norm or squared magnitude
Definition vec2i.hpp:220
constexpr Vector2I & operator+=(const Vector2I &rhs) noexcept
this = this + rhs, component wise.
Definition vec2i.hpp:148
constexpr const_iterator cbegin() const noexcept
Definition vec2i.hpp:91
constexpr bool is_zero() const noexcept
Definition vec2i.hpp:213
constexpr Vector2I & scale(const value_type s) noexcept
this = this * s, component wise.
Definition vec2i.hpp:144
constexpr Vector2I & operator*=(const Vector2I &s) noexcept
this = this * {s.x, s.y}, component wise.
Definition vec2i.hpp:164
constexpr Vector2I(const value_type x_, const value_type y_) noexcept
Definition vec2i.hpp:74
value_type & reference
Definition vec2i.hpp:46
constexpr Vector2I & set(const value_type vx, const value_type vy) noexcept
TODO constexpr bool operator<=>(const vec2i_t& rhs ) const noexcept { return ... }...
Definition vec2i.hpp:120
Value_type value_type
Definition vec2i.hpp:43
constexpr Vector2I & operator=(Vector2I &&) noexcept=default
constexpr value_type length() const noexcept
Return the length of this vector, a.k.a the norm or magnitude
Definition vec2i.hpp:227
static constexpr int value_alignment
Definition vec2i.hpp:52
jau::float_bytes< sizeof(value_type)>::type float_type
Definition vec2i.hpp:60
bool intersects(const Vector2I &o)
Definition vec2i.hpp:247
static constexpr const size_t byte_size
Definition vec2i.hpp:58
std::string toString() const noexcept
Definition vec2i.hpp:211
value_type * pointer
Definition vec2i.hpp:44
constexpr value_type operator[](size_t i) const noexcept
Returns read-only component.
Definition vec2i.hpp:85
void rotate(const float_type sin, const float_type cos, const Vector2I &ctr)
Definition vec2i.hpp:203
constexpr Vector2I & operator*=(const value_type s) noexcept
this = this * s, component wise.
Definition vec2i.hpp:183
constexpr bool operator==(const Vector2I &rhs) const noexcept
Definition vec2i.hpp:109
constexpr_cxx26 void rotate(const float_type radians, const Vector2I &ctr)
Definition vec2i.hpp:198
constexpr Vector2I & operator=(const Vector2I &) noexcept=default
constexpr Vector2I & set(const_iterator xy) noexcept
this = xy, returns this.
Definition vec2i.hpp:124
constexpr Vector2I & add(const value_type dx, const value_type dy) noexcept
this = this + {sx, sy}, component wise.
Definition vec2i.hpp:132
constexpr Vector2I(const value_type v) noexcept
Definition vec2i.hpp:71
constexpr iterator begin() noexcept
Definition vec2i.hpp:100
constexpr Vector2I & mul(const value_type sx, const value_type sy) noexcept
this = this * {sx, sy}, component wise.
Definition vec2i.hpp:140
constexpr Vector2I copy() noexcept
Definition vec2i.hpp:82
const value_type & const_reference
Definition vec2i.hpp:47
constexpr Vector2I & normalize() noexcept
Normalize this vector in place, returns *this.
Definition vec2i.hpp:233
static constexpr const value_type one
Definition vec2i.hpp:63
constexpr Vector2I & operator/=(const value_type s) noexcept
this = this * s, component wise.
Definition vec2i.hpp:193
static constexpr const size_t components
Definition vec2i.hpp:55
constexpr reference operator[](size_t i) noexcept
Returns writeable reference to component.
Definition vec2i.hpp:94
const value_type * const_iterator
Definition vec2i.hpp:49
constexpr Vector2I & operator/=(const Vector2I &s) noexcept
this = this / {s.x, s.y}, component wise.
Definition vec2i.hpp:173
#define constexpr_cxx26
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 jau::sint_bytes_t< sizeof(T)> round_to_int(const T v) noexcept
Returns the rounded value cast to int.
Point2I< int > Point2i
Definition vec2i.hpp:343
constexpr Quaternion< T > operator-(const Quaternion< T > &lhs, const Quaternion< T > &rhs) noexcept
Vector2I< int > Vec2i
Definition vec2i.hpp:328
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
constexpr Matrix4< T > operator*(const Matrix4< T > &lhs, const Matrix4< T > &rhs) noexcept
Definition mat4f.hpp:1906
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
Vector2I< Value_type > Point2I
Point2I alias of Vector2I.
Definition vec2i.hpp:341
uint8_t Value_type