jaulib v1.3.0
Jau Support Library (C++, Java, ..)
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 <cstdint>
30#include <cassert>
31#include <limits>
32#include <string>
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 integer components.
46 */
47 template<typename Value_type,
48 std::enable_if_t<std::is_integral_v<Value_type>, bool> = true>
49 struct alignas(Value_type) Vector2I {
52 typedef const value_type* const_pointer;
56 typedef const value_type* const_iterator;
57
58 typedef typename jau::float_bytes<sizeof(value_type)>::type float_type;
59
60 constexpr static const value_type zero = value_type(0);
61 constexpr static const value_type one = value_type(1);
62
63 /** Number of components */
64 constexpr static const size_t components = 2;
65
66 /** Size in bytes (aligned) */
67 constexpr static const size_t byte_size = components * sizeof(value_type);
68
71
72 constexpr Vector2I() noexcept
73 : x(zero), y(zero) {}
74
75 constexpr Vector2I(const value_type v) noexcept
76 : x(v), y(v) {}
77
78 constexpr Vector2I(const value_type x_, const value_type y_) noexcept
79 : x(x_), y(y_) {}
80
81 constexpr Vector2I(const Vector2I& o) noexcept = default;
82 constexpr Vector2I(Vector2I&& o) noexcept = default;
83 constexpr Vector2I& operator=(const Vector2I&) noexcept = default;
84 constexpr Vector2I& operator=(Vector2I&&) noexcept = default;
85
86 /** Returns read-only component */
87 constexpr value_type operator[](size_t i) const noexcept {
88 assert(i < 2);
89 return (&x)[i];
90 }
91
92 explicit operator const_pointer() const noexcept { return &x; }
93 constexpr const_iterator cbegin() const noexcept { return &x; }
94
95 /** Returns writeable reference to component */
96 constexpr reference operator[](size_t i) noexcept {
97 assert(i < 2);
98 return (&x)[i];
99 }
100
101 explicit operator pointer() noexcept { return &x; }
102 constexpr iterator begin() noexcept { return &x; }
103
104 /** xy = this, returns xy. */
105 constexpr iterator get(iterator xy) const noexcept {
106 xy[0] = x;
107 xy[1] = y;
108 return xy;
109 }
110
111 constexpr bool operator==(const Vector2I& rhs ) const noexcept {
112 if( this == &rhs ) {
113 return true;
114 }
115 return x == rhs.x && y == rhs.y;
116 }
117 /** TODO
118 constexpr bool operator<=>(const vec2i_t& rhs ) const noexcept {
119 return ...
120 } */
121
122 constexpr Vector2I& set(const value_type vx, const value_type vy) noexcept
123 { x=vx; y=vy; return *this; }
124
125 /** this = xy, returns this. */
126 constexpr Vector2I& set(const_iterator xy) noexcept
127 { x=xy[0]; y=xy[1]; return *this; }
128
129 /** this = this + {sx, sy}, returns this. */
130 constexpr Vector2I& add(const value_type dx, const value_type dy) noexcept
131 { x+=dx; y+=dy; return *this; }
132
133 /** this = this * {sx, sy}, returns this. */
134 constexpr Vector2I& mul(const value_type sx, const value_type sy) noexcept
135 { x*=sx; y*=sy; return *this; }
136
137 /** this = this * s, returns this. */
138 constexpr Vector2I& scale(const value_type s) noexcept
139 { x*=s; y*=s; return *this; }
140
141 /** this = this + rhs, returns this. */
142 constexpr Vector2I& operator+=(const Vector2I& rhs ) noexcept {
143 x+=rhs.x; y+=rhs.y;
144 return *this;
145 }
146
147 /** this = this - rhs, returns this. */
148 constexpr Vector2I& operator-=(const Vector2I& rhs ) noexcept {
149 x-=rhs.x; y-=rhs.y;
150 return *this;
151 }
152
153 /**
154 * Scale this vector with given scale factor
155 * @param s scale factor
156 * @return this instance
157 */
158 constexpr Vector2I& operator*=(const value_type s ) noexcept {
159 x*=s; y*=s;
160 return *this;
161 }
162
163 /**
164 * Divide 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 constexpr_cxx26 void rotate(const float_type radians, const Vector2I& ctr) {
174 const float_type cos = std::cos(radians);
175 const float_type sin = std::sin(radians);
176 rotate(sin, cos, ctr);
177 }
178 void rotate(const float_type sin, const float_type cos, const Vector2I& ctr) {
179 const float_type x0 = static_cast<float_type>(x - ctr.x);
180 const float_type y0 = static_cast<float_type>(y - ctr.y);
181 const value_type tmp = jau::round_to_int<float_type>( x0 * cos - y0 * sin ) + ctr.x;
182 y = jau::round_to_int<float_type>( x0 * sin + y0 * cos ) + ctr.y;
183 x = tmp;
184 }
185
186 std::string toString() const noexcept { return std::to_string(x)+" / "+std::to_string(y); }
187
188 constexpr bool is_zero() const noexcept {
189 return jau::is_zero(x) && jau::is_zero(y);
190 }
191
192 /**
193 * Return the squared length of this vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i>
194 */
195 constexpr value_type length_sq() const noexcept {
196 return x*x + y*y;
197 }
198
199 /**
200 * Return the length of this vector, a.k.a the <i>norm</i> or <i>magnitude</i>
201 */
202 constexpr value_type length() const noexcept {
203 // return jau::round_to_int<float_type>( std::sqrt<float_type>( length_sq() ) );
204 return jau::round_to_int<float_type>( std::sqrt( static_cast<float_type> ( length_sq() )) );
205 }
206
207 /** Normalize this vector in place, returns *this */
208 constexpr Vector2I& normalize() noexcept {
209 const value_type lengthSq = length_sq();
210 if ( jau::is_zero( lengthSq ) ) {
211 x = zero;
212 y = zero;
213 } else {
214 const float_type invSqr = one / static_cast<float_type>( std::sqrt(lengthSq) );
215 x = jau::round_to_int<float_type>( x * invSqr );
216 y = jau::round_to_int<float_type>( x * invSqr );
217 }
218 return *this;
219 }
220
221
222 bool intersects(const Vector2I& o) {
223 return x == o.x && y == o.y;
224 }
225 };
226
227 template<typename T,
228 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
229 constexpr Vector2I<T> operator+(const Vector2I<T>& lhs, const Vector2I<T>& rhs ) noexcept {
230 // Returning a Vector2I<T> object from the returned reference of operator+=()
231 // may hinder copy-elision or "named return value optimization" (NRVO).
232 // return Vector2I<T>(lhs) += rhs;
233
234 // Returning named object allows copy-elision (NRVO),
235 // only one object is created 'on target'.
236 Vector2I<T> r(lhs); r += rhs; return r;
237 }
238
239 template<typename T,
240 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
241 constexpr Vector2I<T> operator-(const Vector2I<T>& lhs, const Vector2I<T>& rhs ) noexcept {
242 Vector2I<T> r(lhs); r -= rhs; return r;
243 }
244
245 template<typename T,
246 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
247 constexpr Vector2I<T> operator*(const Vector2I<T>& lhs, const float s ) noexcept {
248 Vector2I<T> r(lhs); r *= s; return r;
249 }
250
251 template<typename T,
252 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
253 constexpr Vector2I<T> operator*(const float s, const Vector2I<T>& rhs) noexcept {
254 Vector2I<T> r(rhs); r *= s; return r;
255 }
256
257 template<typename T,
258 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
259 constexpr Vector2I<T> operator/(const Vector2I<T>& lhs, const float s ) noexcept {
260 Vector2I<T> r(lhs); r /= s; return r;
261 }
262
263 template<typename T,
264 std::enable_if_t<std::numeric_limits<T>::is_integer, bool> = true>
265 std::ostream& operator<<(std::ostream& out, const Vector2I<T>& v) noexcept {
266 return out << v.toString();
267 }
268
270 static_assert(alignof(int) == alignof(Vec2i));
271 static_assert(sizeof(int)*2 == sizeof(Vec2i));
272
273 /**@}*/
274
275} // namespace jau::math
276
277#endif /* JAU_VEC2I_HPP_ */
278
std::string to_string(const alphabet &v) noexcept
Definition: base_codec.hpp:97
#define constexpr_cxx26
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 Quaternion< T > operator-(const Quaternion< T > &lhs, const Quaternion< T > &rhs) noexcept
Vector2I< int > Vec2i
Definition: vec2i.hpp:269
constexpr Vector2F< T > operator/(const Vector2F< T > &lhs, const T s) noexcept
Definition: vec2f.hpp:346
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
2D vector using two integer components.
Definition: vec2i.hpp:49
constexpr Vector2I & operator-=(const Vector2I &rhs) noexcept
this = this - rhs, returns this.
Definition: vec2i.hpp:148
constexpr Vector2I(const Vector2I &o) noexcept=default
constexpr Vector2I(Vector2I &&o) noexcept=default
constexpr iterator get(iterator xy) const noexcept
xy = this, returns xy.
Definition: vec2i.hpp:105
value_type * iterator
Definition: vec2i.hpp:55
const value_type * const_pointer
Definition: vec2i.hpp:52
constexpr Vector2I() noexcept
Definition: vec2i.hpp:72
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:195
constexpr Vector2I & operator+=(const Vector2I &rhs) noexcept
this = this + rhs, returns this.
Definition: vec2i.hpp:142
constexpr const_iterator cbegin() const noexcept
Definition: vec2i.hpp:93
constexpr bool is_zero() const noexcept
Definition: vec2i.hpp:188
constexpr Vector2I & scale(const value_type s) noexcept
this = this * s, returns this.
Definition: vec2i.hpp:138
constexpr Vector2I(const value_type x_, const value_type y_) noexcept
Definition: vec2i.hpp:78
value_type & reference
Definition: vec2i.hpp:53
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:122
Value_type value_type
Definition: vec2i.hpp:50
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:202
value_type x
Definition: vec2i.hpp:69
jau::float_bytes< sizeof(value_type)>::type float_type
Definition: vec2i.hpp:58
bool intersects(const Vector2I &o)
Definition: vec2i.hpp:222
std::string toString() const noexcept
Definition: vec2i.hpp:186
value_type * pointer
Definition: vec2i.hpp:51
void rotate(const float_type sin, const float_type cos, const Vector2I &ctr)
Definition: vec2i.hpp:178
value_type y
Definition: vec2i.hpp:70
constexpr Vector2I & operator*=(const value_type s) noexcept
Scale this vector with given scale factor.
Definition: vec2i.hpp:158
constexpr bool operator==(const Vector2I &rhs) const noexcept
Definition: vec2i.hpp:111
constexpr_cxx26 void rotate(const float_type radians, const Vector2I &ctr)
Definition: vec2i.hpp:173
constexpr Vector2I & operator=(const Vector2I &) noexcept=default
constexpr Vector2I & set(const_iterator xy) noexcept
this = xy, returns this.
Definition: vec2i.hpp:126
constexpr Vector2I & add(const value_type dx, const value_type dy) noexcept
this = this + {sx, sy}, returns this.
Definition: vec2i.hpp:130
constexpr Vector2I(const value_type v) noexcept
Definition: vec2i.hpp:75
constexpr iterator begin() noexcept
Definition: vec2i.hpp:102
constexpr Vector2I & mul(const value_type sx, const value_type sy) noexcept
this = this * {sx, sy}, returns this.
Definition: vec2i.hpp:134
const value_type & const_reference
Definition: vec2i.hpp:54
constexpr Vector2I & normalize() noexcept
Normalize this vector in place, returns *this.
Definition: vec2i.hpp:208
constexpr Vector2I & operator/=(const value_type s) noexcept
Divide this vector with given scale factor.
Definition: vec2i.hpp:168
constexpr reference operator[](size_t i) noexcept
Returns writeable reference to component.
Definition: vec2i.hpp:96
const value_type * const_iterator
Definition: vec2i.hpp:56
uint8_t Value_type