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