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