opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
closed_interval.h
Go to the documentation of this file.
1#pragma once
2
5
6#include <concepts>
7#include <optional>
8#include <utility>
9
10namespace osc
11{
12 // Represents a 1D, axis-aligned, bounding segment along a single dimension in
13 // a caller-defined coordinate system. The bounding segment includes both the
14 // minimum and maximum endpoints (it is "closed").
15 //
16 // The 2D equivalent to a `ClosedInterval` is a `Rect`. The 3D equivalent is
17 // an `AABB`.
18 template<typename T>
19 requires std::equality_comparable<T> and std::totally_ordered<T>
21
22 constexpr ClosedInterval() = default;
23
25 lower{std::move(lower_)},
26 upper{std::move(upper_)}
27 {}
28
29 friend bool operator==(const ClosedInterval&, const ClosedInterval&) = default;
30
31 // returns the diameter of a discrete step that satisfies the following equation:
32 //
33 // lower + nsteps * step_size(nsteps) == upper
34 //
35 // such that it's compatible with 0-indexed discretization, i.e.:
36 //
37 // for (int step = 0; step < nsteps; ++step) {
38 // // first iteration: `value == lower`
39 // // last iteration (if nsteps > 1): `value == upper`
40 // T value = lower + step * step_size(nsteps);
41 // }
42 //
43 // i.e. it describes how the `ClosedInterval` should be discretized while
44 // including the endpoints
45 template<std::integral U>
46 constexpr T step_size(U nsteps) const
47 {
48 if (nsteps <= 1) {
49 return upper - lower; // edge-case
50 }
51
52 return (upper - lower) / static_cast<T>((static_cast<std::make_unsigned_t<U>>(nsteps) - 1));
53 }
54
55 // returns the equivalent normalized interpolant that could be used as an argument
56 // to `lerp` between the interval's endpoints. E.g.:
57 //
58 // - normalized_interpolant_at(lower) == 0.0f
59 // - normalized_interpolant_at(upper) == 1.0f
60 //
61 // an out-of-bounds argument behaves as-if `lerp`ing along the line created between
62 // `lower` and `upper`
63 constexpr T normalized_interpolant_at(T v) const
64 {
65 if (lower == upper) {
66 return T{0}; // the inverse of `std::lerp`'s behavior (ignoring `std::isfinite`)
67 }
68 else {
69 return (v - lower) / (upper - lower);
70 }
71 }
72
73 // returns the absolute difference between the endpoints
74 constexpr T length() const
75 {
76 return abs(upper - lower);
77 }
78
79 // returns `length() / 2`
80 constexpr T half_length() const
81 {
82 return length() / T{2};
83 }
84
85 constexpr bool contains(T v) const
86 {
87 return lower <= v and v <= upper;
88 }
89
92 };
93
94 // returns the unit interval for the given floating-point `T`
95 template<std::floating_point T>
97 {
98 return ClosedInterval<T>(T{0}, T{1});
99 }
100
101 // returns a `ClosedInterval<T>` with `lower == interval.lower - abs_amount` and
102 // `upper == interval.upper + abs_amount`
103 template<typename T>
108
109 // returns a `ClosedInterval` that tightly bounds `x`
110 template<typename T>
112 {
113 return ClosedInterval<T>{x, x};
114 }
115
116 // returns a `ClosedInterval` that tightly bounds both `x` and `y`
117 template<typename T>
119 {
120 return ClosedInterval<T>{min(x.lower, y), max(x.upper, y)};
121 }
122
123 // returns a `ClosedInterval` that tightly bounds both `x` (if present) and `y`
124 template<typename T>
125 constexpr ClosedInterval<T> bounding_interval_of(const std::optional<ClosedInterval<T>>& x, const T& y)
126 {
127 return x ? bounding_interval_of(*x, y) : bounding_interval_of(y);
128 }
129
130 // returns a `ClosedInterval` that tightly bounds both `x` and `y`
131 template<typename T>
133 {
134 return ClosedInterval<T>{min(x.lower, y.lower), max(x.upper, y.upper)};
135 }
136
137 // Returns a `ClosedInterval` that tightly bounds both `x` (if present) and `y`
138 template<typename T>
140 {
141 return x ? bounding_interval_of(*x, y) : y;
142 }
143
144 // Returns `clamp(v, interval.lower, interval.upper`.
145 template<typename T>
146 constexpr const T& clamp(const T& v, const ClosedInterval<T>& interval)
147 {
148 using osc::clamp;
149 return clamp(v, interval.lower, interval.upper);
150 }
151}
Definition custom_decoration_generator.h:5
constexpr auto min(Angle< Rep1, Units1 > x, Angle< Rep2, Units2 > y) -> std::common_type_t< decltype(x), decltype(y)>
Definition angle.h:267
constexpr ClosedInterval< T > unit_interval()
Definition closed_interval.h:96
constexpr Angle< Rep, Units > clamp(const Angle< Rep, Units > &v, const AngleMin &min, const AngleMax &max)
Definition angle.h:303
constexpr ClosedInterval< T > expand_by_absolute_amount(const ClosedInterval< T > &interval, T abs_amount)
Definition closed_interval.h:104
constexpr auto max(Angle< Rep1, Units1 > x, Angle< Rep2, Units2 > y) -> std::common_type_t< decltype(x), decltype(y)>
Definition angle.h:283
T abs(T num)
Definition common_functions.h:24
constexpr U to(T &&value)
Definition conversion.h:56
and
Definition algorithms.h:158
constexpr ClosedInterval< T > bounding_interval_of(const T &x)
Definition closed_interval.h:111
Definition closed_interval.h:20
constexpr ClosedInterval()=default
friend bool operator==(const ClosedInterval &, const ClosedInterval &)=default
constexpr bool contains(T v) const
Definition closed_interval.h:85
constexpr T half_length() const
Definition closed_interval.h:80
constexpr T step_size(U nsteps) const
Definition closed_interval.h:46
T upper
Definition closed_interval.h:91
T lower
Definition closed_interval.h:90
constexpr ClosedInterval(T lower_, T upper_)
Definition closed_interval.h:24
constexpr T normalized_interpolant_at(T v) const
Definition closed_interval.h:63
constexpr T length() const
Definition closed_interval.h:74