1use std::ops::{RangeFrom, RangeFull, RangeInclusive, RangeToInclusive};
2
3#[repr(C)]
5#[derive(Clone, Copy, Debug, PartialEq)]
6#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
7#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
8pub struct Rangef {
9 pub min: f32,
10 pub max: f32,
11}
12
13impl Rangef {
14 pub const EVERYTHING: Self = Self {
16 min: f32::NEG_INFINITY,
17 max: f32::INFINITY,
18 };
19
20 pub const NOTHING: Self = Self {
23 min: f32::INFINITY,
24 max: f32::NEG_INFINITY,
25 };
26
27 pub const NAN: Self = Self {
29 min: f32::NAN,
30 max: f32::NAN,
31 };
32
33 #[inline]
34 pub fn new(min: f32, max: f32) -> Self {
35 Self { min, max }
36 }
37
38 #[inline]
39 pub fn point(min_and_max: f32) -> Self {
40 Self {
41 min: min_and_max,
42 max: min_and_max,
43 }
44 }
45
46 #[inline]
48 pub fn span(self) -> f32 {
49 self.max - self.min
50 }
51
52 #[inline]
54 pub fn center(self) -> f32 {
55 0.5 * (self.min + self.max)
56 }
57
58 #[inline]
59 #[must_use]
60 pub fn contains(self, x: f32) -> bool {
61 self.min <= x && x <= self.max
62 }
63
64 #[inline]
66 #[must_use]
67 pub fn clamp(self, x: f32) -> f32 {
68 x.clamp(self.min, self.max)
69 }
70
71 #[inline]
73 pub fn as_positive(self) -> Self {
74 Self {
75 min: self.min.min(self.max),
76 max: self.min.max(self.max),
77 }
78 }
79
80 #[inline]
82 #[must_use]
83 pub fn shrink(self, amnt: f32) -> Self {
84 Self {
85 min: self.min + amnt,
86 max: self.max - amnt,
87 }
88 }
89
90 #[inline]
92 #[must_use]
93 pub fn expand(self, amnt: f32) -> Self {
94 Self {
95 min: self.min - amnt,
96 max: self.max + amnt,
97 }
98 }
99
100 #[inline]
102 #[must_use]
103 pub fn flip(self) -> Self {
104 Self {
105 min: self.max,
106 max: self.min,
107 }
108 }
109
110 #[inline]
121 #[must_use]
122 pub fn intersection(self, other: Self) -> Self {
123 Self {
124 min: self.min.max(other.min),
125 max: self.max.min(other.max),
126 }
127 }
128
129 #[inline]
139 #[must_use]
140 pub fn intersects(self, other: Self) -> bool {
141 other.min <= self.max && self.min <= other.max
142 }
143}
144
145impl From<Rangef> for RangeInclusive<f32> {
146 #[inline]
147 fn from(Rangef { min, max }: Rangef) -> Self {
148 min..=max
149 }
150}
151
152impl From<&Rangef> for RangeInclusive<f32> {
153 #[inline]
154 fn from(&Rangef { min, max }: &Rangef) -> Self {
155 min..=max
156 }
157}
158
159impl From<RangeInclusive<f32>> for Rangef {
160 #[inline]
161 fn from(range: RangeInclusive<f32>) -> Self {
162 Self::new(*range.start(), *range.end())
163 }
164}
165
166impl From<&RangeInclusive<f32>> for Rangef {
167 #[inline]
168 fn from(range: &RangeInclusive<f32>) -> Self {
169 Self::new(*range.start(), *range.end())
170 }
171}
172
173impl From<RangeFrom<f32>> for Rangef {
174 #[inline]
175 fn from(range: RangeFrom<f32>) -> Self {
176 Self::new(range.start, f32::INFINITY)
177 }
178}
179
180impl From<&RangeFrom<f32>> for Rangef {
181 #[inline]
182 fn from(range: &RangeFrom<f32>) -> Self {
183 Self::new(range.start, f32::INFINITY)
184 }
185}
186
187impl From<RangeFull> for Rangef {
188 #[inline]
189 fn from(_: RangeFull) -> Self {
190 Self::new(f32::NEG_INFINITY, f32::INFINITY)
191 }
192}
193
194impl From<&RangeFull> for Rangef {
195 #[inline]
196 fn from(_: &RangeFull) -> Self {
197 Self::new(f32::NEG_INFINITY, f32::INFINITY)
198 }
199}
200
201impl From<RangeToInclusive<f32>> for Rangef {
202 #[inline]
203 fn from(range: RangeToInclusive<f32>) -> Self {
204 Self::new(f32::NEG_INFINITY, range.end)
205 }
206}
207
208impl PartialEq<RangeInclusive<f32>> for Rangef {
209 #[inline]
210 fn eq(&self, other: &RangeInclusive<f32>) -> bool {
211 self.min == *other.start() && self.max == *other.end()
212 }
213}
214
215impl PartialEq<Rangef> for RangeInclusive<f32> {
216 #[inline]
217 fn eq(&self, other: &Rangef) -> bool {
218 *self.start() == other.min && *self.end() == other.max
219 }
220}