pub trait StableInterpolate: Clone {
// Required method
fn interpolate_stable(&self, other: &Self, t: f32) -> Self;
// Provided methods
fn interpolate_stable_assign(&mut self, other: &Self, t: f32) { ... }
fn smooth_nudge(&mut self, target: &Self, decay_rate: f32, delta: f32) { ... }
}
Expand description
A type with a natural interpolation that provides strong subdivision guarantees.
Although the only required method is interpolate_stable
, many things are expected of it:
-
The notion of interpolation should follow naturally from the semantics of the type, so that inferring the interpolation mode from the type alone is sensible.
-
The interpolation recovers something equivalent to the starting value at
t = 0.0
and likewise with the ending value att = 1.0
. They do not have to be data-identical, but they should be semantically identical. For example,Quat::slerp
doesn’t always yield its second rotation input exactly att = 1.0
, but it always returns an equivalent rotation. -
Importantly, the interpolation must be subdivision-stable: for any interpolation curve between two (unnamed) values and any parameter-value pairs
(t0, p)
and(t1, q)
, the interpolation curve betweenp
andq
must be the linear reparametrization of the original interpolation curve restricted to the interval[t0, t1]
.
The last of these conditions is very strong and indicates something like constant speed. It is called “subdivision stability” because it guarantees that breaking up the interpolation into segments and joining them back together has no effect.
Here is a diagram depicting it:
top curve = u.interpolate_stable(v, t)
t0 => p t1 => q
|-------------|---------|-------------|
0 => u / \ 1 => v
/ \
/ \
/ linear \
/ reparametrization \
/ t = t0 * (1 - s) + t1 * s \
/ \
|-------------------------------------|
0 => p 1 => q
bottom curve = p.interpolate_stable(q, s)
Note that some common forms of interpolation do not satisfy this criterion. For example,
Quat::lerp
and Rot2::nlerp
are not subdivision-stable.
Furthermore, this is not to be used as a general trait for abstract interpolation. Consumers rely on the strong guarantees in order for behavior based on this trait to be well-behaved.
Required Methods§
Sourcefn interpolate_stable(&self, other: &Self, t: f32) -> Self
fn interpolate_stable(&self, other: &Self, t: f32) -> Self
Interpolate between this value and the other
given value using the parameter t
. At
t = 0.0
, a value equivalent to self
is recovered, while t = 1.0
recovers a value
equivalent to other
, with intermediate values interpolating between the two.
See the trait-level documentation for details.
Provided Methods§
Sourcefn interpolate_stable_assign(&mut self, other: &Self, t: f32)
fn interpolate_stable_assign(&mut self, other: &Self, t: f32)
A version of interpolate_stable
that assigns the result to self
for convenience.
Sourcefn smooth_nudge(&mut self, target: &Self, decay_rate: f32, delta: f32)
fn smooth_nudge(&mut self, target: &Self, decay_rate: f32, delta: f32)
Smoothly nudge this value towards the target
at a given decay rate. The decay_rate
parameter controls how fast the distance between self
and target
decays relative to
the units of delta
; the intended usage is for decay_rate
to generally remain fixed,
while delta
is something like delta_time
from an updating system. This produces a
smooth following of the target that is independent of framerate.
More specifically, when this is called repeatedly, the result is that the distance between
self
and a fixed target
attenuates exponentially, with the rate of this exponential
decay given by decay_rate
.
For example, at decay_rate = 0.0
, this has no effect.
At decay_rate = f32::INFINITY
, self
immediately snaps to target
.
In general, higher rates mean that self
moves more quickly towards target
.
§Example
let mut object_position: Vec3 = Vec3::ZERO;
let target_position: Vec3 = Vec3::new(2.0, 3.0, 5.0);
// Decay rate of ln(10) => after 1 second, remaining distance is 1/10th
let decay_rate = f32::ln(10.0);
// Calling this repeatedly will move `object_position` towards `target_position`:
object_position.smooth_nudge(&target_position, decay_rate, delta_time);
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
Implementations on Foreign Types§
Source§impl<T: StableInterpolate> StableInterpolate for (T₁, T₂, …, Tₙ)
impl<T: StableInterpolate> StableInterpolate for (T₁, T₂, …, Tₙ)
This trait is implemented for tuples up to 11 items long.