7#include <glm/common.hpp>
18 template <
template<
typename>
typename HASHER,
typename FIRST,
typename... T>
21 static inline constexpr struct bounding_box_for_t {} bounding_box_for;
26 glm::tvec2<T> p1 = { 0,0 };
27 glm::tvec2<T> p2 = { 0,0 };
29 using tvec = glm::tvec2<T>;
34 explicit constexpr trec2(std::span<tvec const>
points)
noexcept
36 *
this = trec2::exclusive();
41 template <std::same_as<tvec>... ARGS>
42 explicit constexpr trec2(bounding_box_for_t,
ARGS&&...
args)
noexcept
44 *
this = trec2::exclusive();
45 (this->include(std::forward<ARGS>(
args)), ...);
48 constexpr explicit trec2(tvec a)
noexcept : p1(), p2(a) { }
50 constexpr trec2(
const trec2&)
noexcept =
default;
57 constexpr trec2& operator=(
const trec2&)
noexcept =
default;
61 template <std::same_as<tvec>... ARGS>
62 static constexpr trec2 from_points(
ARGS&&...
args)
noexcept {
return trec2(bounding_box_for, std::forward<ARGS>(
args)...); }
63 static constexpr trec2 from_size(tvec
s)
noexcept {
return { tvec{},
s }; };
64 static constexpr trec2 from_size(tvec
p, tvec
s)
noexcept {
return {
p,
p +
s }; };
65 static constexpr trec2 from_size(T x, T y, T
w, T
h)
noexcept {
return { x, y, x +
w, y +
h }; };
66 static constexpr trec2 from_center_and_size(tvec
p, tvec
s)
noexcept {
return {
p -
s / T(2),
p +
s / T(2) }; };
67 static constexpr trec2 from_center_and_size(T x, T y, T
w, T
h)
noexcept {
return { x -
w / T(2), y -
h / T(2), x +
w / T(2), y +
h / T(2) }; };
70 static constexpr trec2
const& exclusive()
noexcept
72 if constexpr (std::numeric_limits<T>::has_infinity)
74 static constexpr trec2 exclusive = { std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), -std::numeric_limits<T>::infinity(), -std::numeric_limits<T>::infinity() };
79 static constexpr trec2 exclusive = { std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::lowest(), std::numeric_limits<T>::lowest() };
83 static constexpr trec2
const& inclusive()
noexcept
85 if constexpr (std::numeric_limits<T>::has_infinity)
87 static constexpr trec2 inclusive = { -std::numeric_limits<T>::infinity(), -std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity() };
92 static constexpr trec2 inclusive = { std::numeric_limits<T>::lowest(), std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max() };
97 constexpr trec2 operator+(tvec
op)
const noexcept {
return { p1 +
op, p2 +
op }; }
98 constexpr trec2& operator+=(tvec
op)
noexcept { p1 +=
op; p2 +=
op;
return *
this; };
99 constexpr trec2 operator-(tvec
op)
const noexcept {
return { p1 -
op, p2 -
op }; }
100 constexpr trec2& operator-=(tvec
op)
noexcept { p1 -=
op; p2 -=
op;
return *
this; };
101 constexpr trec2 operator*(T
op)
const noexcept {
return { p1 *
op, p2 *
op }; }
102 constexpr trec2 operator/(T
op)
const noexcept {
return { p1 /
op, p2 /
op }; }
103 constexpr trec2 operator*(tvec
op)
const noexcept {
return { p1 *
op, p2 *
op }; }
104 constexpr trec2 operator/(tvec
op)
const noexcept {
return { p1 /
op, p2 /
op }; }
106 constexpr auto operator<=>(trec2
const&
other)
const noexcept =
default;
108 constexpr tvec operator[](
size_t i)
const noexcept
113 case 1:
return right_top();
115 case 3:
return left_bottom();
121 template <
typename U> values_t(
U&& left,
U&& top,
U&& right,
U&& bottom) ->
values_t<U>;
123 template <
typename SELF>
124 constexpr auto values(
this SELF&&
self)
noexcept
127 std::forward_like<SELF>(
self.p1.x),
128 std::forward_like<SELF>(
self.p1.y),
129 std::forward_like<SELF>(
self.p2.x),
130 std::forward_like<SELF>(
self.p2.y)
137 constexpr trec2& set_position(tvec
pos)
noexcept { p2 +=
pos - p1; p1 =
pos;
return *
this; }
138 constexpr trec2& set_position(T x, T y)
noexcept { p2.x += x - p1.x; p2.y += y - p1.y; p1 = { x, y };
return *
this; }
139 constexpr trec2& set_x(T x)
noexcept { p2.x += x - p1.x; p1.x = x;
return *
this; }
140 constexpr trec2& set_y(T y)
noexcept { p2.y += y - p1.y; p1.y = y;
return *
this; }
141 constexpr trec2& set_size(tvec size)
noexcept { p2 = p1 + size;
return *
this; }
142 constexpr trec2& set_size(T
w, T
h)
noexcept { p2.x = p1.x +
w; p2.y = p1.y +
h;
return *
this; }
144 constexpr trec2& grow(T
by)
noexcept { p1.x -=
by; p1.y -=
by; p2.x +=
by; p2.y +=
by;
return *
this; }
145 constexpr trec2& shrink(T
by)
noexcept {
return grow(-
by); }
146 constexpr trec2& grow(tvec
by)
noexcept { p1 -=
by; p2 +=
by;
return *
this; }
147 constexpr trec2& shrink(tvec
by)
noexcept {
return grow(-
by); }
148 constexpr trec2 grown(T
by)
const noexcept {
auto copy = *
this; copy.p1.x -=
by; copy.p1.y -=
by; copy.p2.x +=
by; copy.p2.y +=
by;
return copy; }
149 constexpr trec2 shrunk(T
by)
const noexcept {
return grown(-
by); }
150 constexpr trec2 grown(tvec
by)
const noexcept {
auto copy = *
this; copy.p1 -=
by; copy.p2 +=
by;
return copy; }
151 constexpr trec2 shrunk(tvec
by)
const noexcept {
return grown(-
by); }
152 constexpr trec2& grow(T left, T top, T right, T bottom)
noexcept { p1.x -=
left; p1.y -=
top; p2.x +=
right; p2.y +=
bottom;
return *
this; }
153 constexpr trec2& shrink(T left, T top, T right, T bottom)
noexcept {
return grow(-left, -top, -right, -bottom); }
154 constexpr trec2 grown(T left, T top, T right, T bottom)
const noexcept {
auto copy = *
this; copy.p1.x -=
left; copy.p1.y -=
top; copy.p2.x +=
right; copy.p2.y +=
bottom;
return copy; }
155 constexpr trec2 shrunk(T left, T top, T right, T bottom)
const noexcept {
return grown(-left, -top, -right, -bottom); }
157 constexpr trec2 at_position(tvec
pos)
const noexcept {
auto copy = *
this; copy.set_position(
pos);
return copy; }
158 constexpr trec2 at_position(T x, T y)
const noexcept {
auto copy = *
this; copy.set_position(x, y);
return copy; }
159 constexpr trec2 sized(tvec size)
const noexcept {
auto copy = *
this; copy.set_size(size);
return copy; }
160 constexpr trec2 sized(T
w, T
h)
const noexcept {
auto copy = *
this; copy.set_size(
w,
h);
return copy; }
161 constexpr trec2 translated(tvec
op)
const noexcept {
return *
this +
op; }
162 constexpr trec2 translated(T x, T y)
const noexcept {
return *
this + tvec{ x, y }; }
163 constexpr trec2 scaled(tvec
op)
const noexcept {
return *
this *
op; }
164 constexpr trec2 scaled(T x, T y)
const noexcept {
return *
this * tvec{ x, y }; }
165 constexpr trec2 scaled(T
s)
const noexcept {
return *
this *
s; }
168 constexpr trec2& set_width(T
w)
noexcept { p2.x = p1.x +
w;
return *
this; };
169 constexpr trec2& set_height(T
h)
noexcept { p2.y = p1.y +
h;
return *
this; };
177 constexpr tvec left_bottom()
const noexcept {
return { p1.x, p2.y }; }
178 constexpr tvec right_top()
const noexcept {
return { p2.x, p1.y }; }
180 constexpr tvec half_size()
const noexcept {
return (p2 - p1) / T{ 2 }; }
182 constexpr trec2& set_center(tvec
pos)
noexcept {
const auto hw = half_size(); p1 =
pos -
hw; p2 =
pos +
hw;
return *
this; }
183 constexpr trec2 at_center(tvec
pos)
const noexcept {
auto copy = *
this; copy.set_center(
pos);
return copy; }
185 constexpr trec2 local()
const noexcept {
return { tvec{}, size() }; }
186 constexpr trec2 relative_to(trec2
const&
other)
const noexcept {
return { p1 -
other.position(), p2 -
other.position() }; }
190 constexpr glm::vec2 to_rect_space(tvec
world_space)
const noexcept {
return glm::vec2{
world_space - p1 } / glm::vec2{ size() }; }
191 constexpr tvec to_world_space(glm::vec2
rect_space)
const noexcept {
return tvec{
rect_space * glm::vec2{ size() } } + p1; }
193 constexpr trec2& include(tvec
pt)
noexcept { this->p1 = glm::min(this->p1,
pt); this->p2 = glm::max(this->p2,
pt);
return *
this; };
194 constexpr trec2& include(trec2
const&
rec)
noexcept {
return this->include(
rec.p1).include(
rec.p2); };
196 constexpr trec2 including(tvec
pt)
const noexcept {
return { glm::min(this->p1,
pt), glm::max(this->p2,
pt) }; };
197 constexpr trec2 including(trec2
const&
rec)
const noexcept {
return this->include(
rec.p1).include(
rec.p2); };
199 constexpr bool intersects(trec2
const&
other)
const noexcept
204 constexpr trec2 intersection(trec2
const&
other)
const noexcept
206 auto x1 = std::max(std::min(p1.x, p2.x), std::min(
other.p1.x,
other.p2.x));
207 auto y1 = std::max(std::min(p1.y, p2.y), std::min(
other.p1.y,
other.p2.y));
208 auto x2 = std::min(std::max(p1.x, p2.x), std::max(
other.p1.x,
other.p2.x));
209 auto y2 = std::min(std::max(p1.y, p2.y), std::max(
other.p1.y,
other.p2.y));
213 constexpr trec2 clipped_to(trec2
const&
other)
const noexcept
215 return intersection(
other);
218 constexpr bool contains(glm::vec<2, T>
const&
other)
const noexcept
231 return p1.x <= p2.x && p1.y <= p2.y;
237 if (copy.p1.x > copy.p2.x) std::swap(copy.p1.x, copy.p2.x);
238 if (copy.p1.y > copy.p2.y) std::swap(copy.p1.y, copy.p2.y);
242 constexpr trec2& make_valid()
noexcept
244 if (p1.x > p2.x) std::swap(p1.x, p2.x);
245 if (p1.y > p2.y) std::swap(p1.y, p2.y);
249 constexpr std::pair<trec2, trec2> split_vertical(T
top_height)
const noexcept
253 return { trec2::from_size(this->p1, {this->width(),
top_height}), trec2::from_size(this->p1 + tvec{0,
top_height}, {this->width(), this->height() -
top_height}) };
256 constexpr std::pair<trec2, trec2> split_horizontal(T
left_width)
const noexcept
260 return { trec2::from_size(this->p1, {
left_width, this->height()}), trec2::from_size(this->p1 + tvec{
left_width, 0}, {this->width() -
left_width, this->height()})};
263 constexpr T calculate_area()
const noexcept {
return width() * height(); }
265 constexpr T edge_length()
const noexcept {
return (width() + height()) * 2; }
267 constexpr glm::vec2 edge_point_alpha(
double edge_progress)
const
270 const auto w = width();
271 const auto h = height();
272 const auto el = (
w +
h) * 2;
275 return glm::mix(this->left_top(), this->right_top(),
d /
w);
277 return glm::mix(this->right_top(), this->right_bottom(), (
d -
w) /
h);
278 else if (
d <
w +
h +
w)
279 return glm::mix(this->right_bottom(), this->left_bottom(), (
d - (
w +
h)) /
w);
281 return glm::mix(this->left_bottom(), this->left_top(), (
d - (
w +
h +
w)) /
h);
284 constexpr glm::vec2 edge_point(
double edge_pos)
const
286 const auto w = width();
287 const auto h = height();
290 return glm::mix(this->left_top(), this->right_top(),
edge_pos /
w);
292 return glm::mix(this->right_top(), this->right_bottom(), (
edge_pos -
w) /
h);
294 return glm::mix(this->right_bottom(), this->left_bottom(), (
edge_pos - (
w +
h)) /
w);
296 return glm::mix(this->left_bottom(), this->left_top(), (
edge_pos - (
w +
h +
w)) /
h);
304 constexpr glm::vec2 projected(glm::vec2
pt)
const
306 const auto d = (
pt - p1) / size();
307 const auto c = glm::clamp(
d, glm::vec2{ 0 }, glm::vec2{ 1 });
308 return p1 + c * size();
315 template <
typename T>
318 template <
typename T,
typename STRINGIFIER>
319 auto stringify(
STRINGIFIER& str,
trec2<T>& b) {
return str(
'[', b.p1.x,
',', b.p1.y,
',', b.p2.x,
',', b.p2.y,
']'); }
320 template <
typename T,
typename STRINGIFIER>
321 auto stringify(
STRINGIFIER& str,
trec2<T> const& b) {
return str(
'[', b.p1.x,
',', b.p1.y,
',', b.p2.x,
',', b.p2.y,
']'); }
330 return ghassanpl::hash(s.p1, s.p2);
335#include "align+rec2.h"
constexpr auto bit_count
Equal to the number of bits in the type.
constexpr __contains_fn contains
contains(range, el)
@ invalid
Represents an invalid plane number.
Primary namespace for everything in this library.