Recti 1.2.4
Loading...
Searching...
No Matches
interval.hpp
Go to the documentation of this file.
1
5#pragma once
6
7// #include <algorithm> // import std::min, std::max
8#include <utility> // import std::move
9
10#include "generic.hpp"
11
12namespace recti {
13
23 template <typename T = int> class Interval {
24 private:
25 T _lb; //> lower bound
26 T _ub; //> upper bound
27
28 public:
29 using value_type = T;
30
34 constexpr Interval() : _lb{T()}, _ub{T()} {}
35
45 constexpr Interval(T lower, T upper) noexcept
46 : _lb{std::move(lower)}, _ub{std::move(upper)} {}
47
57 explicit constexpr Interval(const T& value) : _lb{value}, _ub{value} {}
58
70 constexpr auto operator=(const T& value) -> Interval& {
71 this->_lb = this->_ub = value;
72 return *this;
73 }
74
82 constexpr auto lb() const -> const T& { return this->_lb; }
83
91 constexpr auto ub() const -> const T& { return this->_ub; }
92
101 constexpr auto measure() const -> T { return this->ub() - this->lb(); }
102
111 constexpr auto is_invalid() const -> bool { return this->lb() > this->ub(); }
112
117
129 template <typename U> //
130 constexpr auto operator==(const Interval<U>& rhs) const -> bool {
131 return this->lb() == rhs.lb() && this->ub() == rhs.ub();
132 }
133
145 template <typename U> //
146 constexpr auto operator!=(const Interval<U>& rhs) const -> bool {
147 return !(*this == rhs);
148 }
149
164 template <typename U> //
165 constexpr auto operator<=>(const U& rhs) const -> std::weak_ordering {
166 if (this->ub() < rhs) return std::weak_ordering::less;
167 if (this->lb() > rhs) return std::weak_ordering::greater;
168 return std::weak_ordering::equivalent;
169 }
170
186 friend constexpr auto operator<=>(const T& lhs, const Interval& rhs) -> std::weak_ordering {
187 if (lhs < rhs.lb()) return std::weak_ordering::less;
188 if (lhs > rhs.ub()) return std::weak_ordering::greater;
189 return std::weak_ordering::equivalent;
190 }
191
193
198
209 constexpr auto operator-() const -> Interval { return {-this->_ub, -this->_lb}; }
210
222 template <typename U> constexpr auto operator+=(const U& value) -> Interval& {
223 this->_lb += value;
224 this->_ub += value;
225 return *this;
226 }
227
239 template <typename U> friend constexpr auto operator+(Interval rhs, const U& value)
240 -> Interval {
241 return rhs += value;
242 }
243
255 friend constexpr auto operator+(const T& value, Interval rhs) -> Interval {
256 return rhs += value;
257 }
258
269 template <typename U> constexpr auto operator-=(const U& value) -> Interval& {
270 this->_lb -= value;
271 this->_ub -= value;
272 return *this;
273 }
274
287 template <typename U> friend constexpr auto operator-(const Interval& rhs, const U& value)
288 -> Interval {
289 auto lower = rhs.lb() - value;
290 auto upper = rhs.ub() - value;
291 return Interval<decltype(lower)>{std::move(lower), std::move(upper)};
292 }
293
304 constexpr auto enlarge_with(const T& value) const {
305 return Interval{this->_lb - value, this->_ub + value};
306 }
307
309
321 template <typename U> // cppcheck-suppress internalAstError
322 constexpr auto overlaps(const U& other_interval) const -> bool {
323 return !(*this < other_interval || other_interval < *this);
324 }
325
343 template <typename U> // cppcheck-suppress internalAstError
344 constexpr auto contains(const U& other_interval) const -> bool {
345 if constexpr (requires { other_interval.lb(); }) {
346 return this->lb() <= other_interval.lb() && other_interval.ub() <= this->ub();
347 } else /* constexpr */ { // assume scalar
348 return this->lb() <= other_interval && other_interval <= this->ub();
349 }
350 }
351
370 template <typename U> //
371 constexpr auto intersect_with(const U& other_interval) const {
372 if constexpr (requires { other_interval.lb(); }) {
373 return Interval<T>{
374 this->lb() > other_interval.lb() ? this->lb() : T(other_interval.lb()),
375 this->ub() < other_interval.ub() ? this->ub() : T(other_interval.ub())};
376 } else /* constexpr */ { // assume scalar
377 return Interval<T>{this->lb() > other_interval ? this->lb() : T(other_interval),
378 this->ub() < other_interval ? this->ub() : T(other_interval)};
379 }
380 }
381
400 template <typename U> //
401 constexpr auto hull_with(const U& other_interval) const {
402 if constexpr (requires { other_interval.lb(); }) {
403 return Interval<T>{
404 this->lb() < other_interval.lb() ? this->lb() : T(other_interval.lb()),
405 this->ub() > other_interval.ub() ? this->ub() : T(other_interval.ub())};
406 } else /* constexpr */ { // assume scalar
407 return Interval<T>{this->lb() < other_interval ? this->lb() : T(other_interval),
408 this->ub() > other_interval ? this->ub() : T(other_interval)};
409 }
410 }
411
430 template <typename U> constexpr auto min_dist_with(const U& other_interval) const -> T {
431 if (*this < other_interval) {
432 return min_dist(this->_ub, other_interval);
433 }
434 if (other_interval < *this) {
435 return min_dist(this->_lb, other_interval);
436 }
437 return T(0);
438 }
439
446 constexpr auto nearest_to(const T& reference_value) const -> T {
447 if (*this < reference_value) {
448 return nearest(this->_ub, reference_value);
449 }
450 if (reference_value < *this) {
451 return nearest(this->_lb, reference_value);
452 }
453 return reference_value;
454 }
455
477 template <typename U> constexpr auto min_dist_change_with(U& other_interval) -> T {
478 if (*this < other_interval) {
479 this->_lb = this->_ub;
480 return min_dist_change(this->_ub, other_interval);
481 }
482 if (other_interval < *this) {
483 this->_ub = this->_lb;
484 return min_dist_change(this->_lb, other_interval);
485 }
486
487 if constexpr (requires { other_interval.lb(); }) {
488 *this = other_interval = this->intersect_with(other_interval);
489 } else /* constexpr */ { // assume scalar
490 this->_ub = this->_lb = other_interval;
491 }
492 return T(0);
493 }
494
500 constexpr auto get_center() const -> T { return this->_lb + (this->_ub - this->_lb) / 2; }
501
507 constexpr auto lower_corner() const -> T { return this->_lb; }
508
514 constexpr auto upper_corner() const -> T { return this->_ub; }
515
529 template <class Stream> friend auto operator<<(Stream& out, const Interval& intvl)
530 -> Stream& {
531 out << "[" << intvl.lb() << ", " << intvl.ub() << "]";
532 return out;
533 }
534 };
535
553 template <typename U1, typename U2> //
554 constexpr auto hull(const U1& left, const U2& right) {
555 if constexpr (requires { left.hull_with(right); }) {
556 return left.hull_with(right);
557 } else if constexpr (requires { right.hull_with(left); }) {
558 return right.hull_with(left);
559 } else /* constexpr */ {
560 return left < right ? Interval<U1>(left, right) : Interval<U2>(right, left);
561 }
562 }
563
578 template <typename U1, typename U2> //
579 constexpr auto enlarge(const U1& left, const U2& right) {
580 if constexpr (requires { left.enlarge_with(right); }) {
581 return left.enlarge_with(right);
582 } else if constexpr (std::is_arithmetic_v<U1>) {
583 return Interval<U1>{left - right, left + right};
584 } else {
585 // No default behavior for non-arithmetic types without enlarge_with
586 // This will cause a compile error if enlarge is called with such types,
587 // which is the desired behavior.
588 return left;
589 }
590 }
591} // namespace recti
Interval.
Definition interval.hpp:23
constexpr auto operator-=(const U &value) -> Interval &
Subtract a scalar value from an Interval object.
Definition interval.hpp:269
friend constexpr auto operator-(const Interval &rhs, const U &value) -> Interval
Subtract a scalar value from an Interval object.
Definition interval.hpp:287
constexpr auto hull_with(const U &other_interval) const
Computes the hull of the current interval with another interval or scalar value.
Definition interval.hpp:401
constexpr auto operator=(const T &value) -> Interval &
Assignment operator.
Definition interval.hpp:70
T value_type
Definition interval.hpp:29
constexpr auto nearest_to(const T &reference_value) const -> T
Find the nearest point to a given value.
Definition interval.hpp:446
constexpr auto operator+=(const U &value) -> Interval &
Add a value to the lower and upper bounds of the interval.
Definition interval.hpp:222
constexpr auto upper_corner() const -> T
Get the upper corner of the interval.
Definition interval.hpp:514
friend constexpr auto operator+(const T &value, Interval rhs) -> Interval
Add (by a scalar)
Definition interval.hpp:255
constexpr auto lb() const -> const T &
lower bound
Definition interval.hpp:82
constexpr auto enlarge_with(const T &value) const
Enlarge the interval by subtracting value from the lower bound and adding value to the upper bound.
Definition interval.hpp:304
constexpr auto measure() const -> T
measure (length)
Definition interval.hpp:101
constexpr auto ub() const -> const T &
upper bound
Definition interval.hpp:91
constexpr auto operator-() const -> Interval
Negation operator for an Interval object.
Definition interval.hpp:209
constexpr auto contains(const U &other_interval) const -> bool
Checks if the current interval contains another interval.
Definition interval.hpp:344
constexpr auto operator==(const Interval< U > &rhs) const -> bool
Equality comparison operator for Interval objects.
Definition interval.hpp:130
friend constexpr auto operator<=>(const T &lhs, const Interval &rhs) -> std::weak_ordering
Spaceship comparison operator for comparing a value with an Interval object.
Definition interval.hpp:186
constexpr auto min_dist_change_with(U &other_interval) -> T
Computes the minimum distance between the current interval and the other_interval interval or scalar ...
Definition interval.hpp:477
constexpr Interval(const T &value)
Construct a new Interval object.
Definition interval.hpp:57
friend constexpr auto operator+(Interval rhs, const U &value) -> Interval
Add a scalar value to an Interval object.
Definition interval.hpp:239
constexpr auto intersect_with(const U &other_interval) const
Computes the intersection of the current interval with another interval or scalar value.
Definition interval.hpp:371
constexpr auto operator!=(const Interval< U > &rhs) const -> bool
Not equal to comparison operator for Interval objects.
Definition interval.hpp:146
constexpr auto operator<=>(const U &rhs) const -> std::weak_ordering
Spaceship comparison operator for Interval objects.
Definition interval.hpp:165
constexpr auto get_center() const -> T
Calculate the center of the interval.
Definition interval.hpp:500
friend auto operator<<(Stream &out, const Interval &intvl) -> Stream &
Overloads the stream insertion operator (<<) to print an Interval object to the given output stream.
Definition interval.hpp:529
constexpr auto overlaps(const U &other_interval) const -> bool
Checks if the current interval overlaps with another interval.
Definition interval.hpp:322
constexpr auto min_dist_with(const U &other_interval) const -> T
Computes the minimum distance between the current interval and the other_interval interval or scalar ...
Definition interval.hpp:430
constexpr Interval()
Construct a new Interval object.
Definition interval.hpp:34
constexpr auto is_invalid() const -> bool
Checks if the interval is invalid.
Definition interval.hpp:111
constexpr auto lower_corner() const -> T
Get the lower corner of the interval.
Definition interval.hpp:507
constexpr Interval(T lower, T upper) noexcept
Construct a new Interval object.
Definition interval.hpp:45
Generic free functions for geometric operations (overlap, intersection, hull, distance).
Definition svg_utils.hpp:12
constexpr auto nearest(const U1 &lhs, const U2 &rhs)
Returns the nearest point on lhs to rhs.
Definition generic.hpp:227
constexpr auto hull(const U1 &left, const U2 &right)
Computes the hull of two objects.
Definition interval.hpp:554
constexpr auto enlarge(const U1 &left, const U2 &right)
Enlarges an interval or scalar value by adding and subtracting a given value.
Definition interval.hpp:579
constexpr auto min_dist_change(U1 &lhs, U2 &rhs)
Calculates the minimum distance between two objects lhs and rhs, with the ability to handle a change ...
Definition generic.hpp:195
constexpr auto min_dist(const U1 &lhs, const U2 &rhs)
Calculates the minimum distance between two objects lhs and rhs.
Definition generic.hpp:166
constexpr auto lower(const U &obj)
Calculates the lower corner of an object.
Definition generic.hpp:281
constexpr auto upper(const U &obj)
Calculates the upper corner of an object.
Definition generic.hpp:299