Skip to main content

glam/
float.rs

1/// A trait for extending [`prim@f32`] and [`prim@f64`] with extra methods.
2///
3/// This trait is sealed and cannot be implemented for types outside of `glam`.
4pub trait FloatExt: crate::sealed::Sealed {
5    /// Performs a linear interpolation between `self` and `rhs` based on the value `s`, using the
6    /// form `self * (1.0 - s) + rhs * s`.
7    ///
8    /// When `s` is `0.0`, the result will be equal to `self`. When `s` is `1.0`, the result will
9    /// be equal to `rhs`. When `s` is outside of the range `[0, 1]`, the result is linearly
10    /// extrapolated.
11    ///
12    /// The result is guaranteed to be `self` at `s == 0.0` and `rhs` at `s == 1.0`, even when the
13    /// values differ greatly in magnitude, but it is not monotonic in `s` for nearly equal inputs
14    /// and may not preserve equal inputs exactly. Consider [`lerp_monotonic`](Self::lerp_monotonic)
15    /// instead when interpolating between values that may be equal or nearly equal.
16    #[must_use]
17    fn lerp(self, rhs: Self, s: Self) -> Self;
18
19    /// Performs a linear interpolation between `self` and `rhs` based on the value `s`, using the
20    /// monotonic form `self + (rhs - self) * s`.
21    ///
22    /// When `s` is `0.0`, the result will be equal to `self`. When `s` is `1.0`, the result will
23    /// be equal to `rhs`. When `s` is outside of the range `[0, 1]`, the result is linearly
24    /// extrapolated.
25    ///
26    /// Prefer this over [`lerp`](Self::lerp) when interpolating between values that may be equal or
27    /// nearly equal: the result is monotonic in `s` and equal inputs are preserved exactly, avoiding
28    /// the rounding jitter that [`lerp`](Self::lerp) can introduce. The tradeoff is that
29    /// `rhs - self` is evaluated first, so this is less accurate than [`lerp`](Self::lerp) when
30    /// `self` and `rhs` differ greatly in magnitude, and overflows to infinity when they have
31    /// opposite signs and large magnitudes.
32    #[must_use]
33    fn lerp_monotonic(self, rhs: Self, s: Self) -> Self;
34
35    /// Returns `v` normalized to the range `[a, b]`.
36    ///
37    /// When `v` is equal to `a` the result will be `0`.  When `v` is equal to `b` will be `1`.
38    ///
39    /// When `v` is outside of the range `[a, b]`, the result is linearly extrapolated.
40    ///
41    /// `a` and `b` must not be equal, otherwise the result will be either infinite or `NAN`.
42    fn inverse_lerp(a: Self, b: Self, v: Self) -> Self;
43
44    /// Performs Hermite interpolation between `0.0` and `1.0` using `x` normalized to `[edge0, edge1]`.
45    ///
46    /// This is equivalent to `t * t * (3.0 - 2.0 * t)`, where `t` is clamped to `[0.0, 1.0]`.
47    /// Results are undefined if `edge0` is greater than or equal to `edge1`.
48    #[must_use]
49    fn smoothstep(self, edge0: Self, edge1: Self) -> Self;
50
51    /// Remap `self` from the input range to the output range.
52    ///
53    /// When `self` is equal to `in_start` this returns `out_start`.
54    /// When `self` is equal to `in_end` this returns `out_end`.
55    ///
56    /// When `self` is outside of the range `[in_start, in_end]`, the result is linearly extrapolated.
57    ///
58    /// `in_start` and `in_end` must not be equal, otherwise the result will be either infinite or `NAN`.
59    #[must_use]
60    fn remap(self, in_start: Self, in_end: Self, out_start: Self, out_end: Self) -> Self;
61
62    /// Returns the fractional part of the input as `self - self.floor()`.
63    ///
64    /// Note that this differs from the Rust implementation of `fract` which returns
65    /// `self - self.trunc()`.
66    ///
67    /// Note that this is fast but not precise for large numbers.
68    fn fract_gl(self) -> Self;
69
70    /// Returns `0.0` if `value < self` and 1.0 otherwise.
71    ///
72    /// Similar to glsl's step(edge, x), which translates into edge.step(x)
73    #[must_use]
74    fn step(self, value: Self) -> Self;
75
76    /// Returns `self` clamped within the range `[0.0, 1.0]`
77    #[must_use]
78    fn saturate(self) -> Self;
79
80    /// Moves `self` towards `rhs` by at most the distance `d`.
81    ///
82    /// When `d` is `0.0`, the result will be equal to `self`. When `d` is greater than or
83    /// equal to the distance between `self` and `rhs`, the result will be equal to `rhs`.
84    /// Will not go past `rhs`.
85    #[must_use]
86    fn move_towards(self, rhs: Self, d: Self) -> Self;
87}