pub trait Signal<Input> {
type Output;
// Required method
fn eval(&self, input: Input) -> Self::Output;
// Provided methods
fn extract<I, J>(self, iterator: I) -> Extract<Self, J> ⓘ
where Self: Sized,
I: IntoIterator<IntoIter = J>,
J: Iterator<Item = Input> { ... }
fn stack<G>(self, signal: G) -> Stack<Self, G>
where Self: Sized { ... }
fn composite<G>(self, signal: G) -> Composite<Self, G>
where Self: Sized { ... }
fn by_ref(&self) -> &Self { ... }
fn sample<I, J>(&self, iterator: I) -> Extract<&Self, J> ⓘ
where Self: Sized,
I: IntoIterator<IntoIter = J>,
J: Iterator<Item = Input> { ... }
}
Expand description
Trait which symbolises the generation or copying of an element.
This trait is fairly similar to core::ops::Index, however it does not retrurn a reference but the element itself. When a struct implements an Index, it usually should be able to implement this trait as well. The other way around does not have to be the case.
Required Associated Types§
Required Methods§
Provided Methods§
Sourcefn extract<I, J>(self, iterator: I) -> Extract<Self, J> ⓘ
fn extract<I, J>(self, iterator: I) -> Extract<Self, J> ⓘ
Helper function if one wants to extract values from the interpolation.
It takes an iterator of items which are inputed into the eval()
method
and returns an iterator of the corresponding outputs.
§Examples
let linear = Linear::builder()
.elements([0.0,3.0])
.knots([0.0,1.0])
.build()?;
let samples = [0.0,0.2,0.4,0.5,0.55,1.0]; // take these samples
let expected = [0.0,0.6,1.2,1.5,1.65,3.0];
for (value, result) in linear.extract(samples).zip(expected) {
assert_f64_near!(value, result);
}
Sourcefn stack<G>(self, signal: G) -> Stack<Self, G>where
Self: Sized,
fn stack<G>(self, signal: G) -> Stack<Self, G>where
Self: Sized,
Stack two signals together
That is for two signal with output T
and R
the created signal output will be (T,R)
.
§Examples
let elements = [1.0,5.0,3.0];
let weights = [1.0,3.0,2.0];
// We assume elements and weights to be huge, such that zipping and collecting them is not viable.
let linear = Linear::builder()
.elements_with_weights(elements.stack(weights))
.knots([0.0,1.0,2.0])
.build()?;
assert_f64_near!(linear.eval(0.5), 4.0);
Sourcefn composite<G>(self, signal: G) -> Composite<Self, G>where
Self: Sized,
fn composite<G>(self, signal: G) -> Composite<Self, G>where
Self: Sized,
Takes two signals and creates a new signal pipelining both signals.
composite()
will return a new signal which will first generate values from the original input
and then use these values as input for the second signal.
In other words, it is the composite of two functions.
§Examples
let elements = [-3.0,-2.0,2.0,3.0]; // In reality these would be 2D points etc.
let curve = Bezier::builder()
.elements(elements)
.normalized::<f64>()
.constant::<4>()
.build().expect("hardcoded");
// we want to change the velocity of our point transversing the curve
let smoothing = FuncEase::new(smoothstep);
let samples = [0.1,0.25];
let corrected_samples : Vec<_> = smoothing.sample(samples).collect();
let results : Vec<_> = curve.sample(corrected_samples).collect();
let smoother_animation = smoothing.composite(curve);
assert_f64_near!(smoother_animation.eval(0.1), results[0]);
assert_f64_near!(smoother_animation.eval(0.25), results[1]);
Sourcefn by_ref(&self) -> &Self
fn by_ref(&self) -> &Self
Get a reference of the signal.
This is useful if one wants to add an adaptor without consuming the original.
Sourcefn sample<I, J>(&self, iterator: I) -> Extract<&Self, J> ⓘ
fn sample<I, J>(&self, iterator: I) -> Extract<&Self, J> ⓘ
Helper function if one wants to sample values from the interpolation.
It takes an iterator of items which are inputed into the eval()
method
and returns an iterator of the corresponding outputs.
This acts the same as signal.by_ref().extract()
.
§Examples
let linear = Linear::builder()
.elements([0.0,3.0])
.knots([0.0,1.0])
.build()?;
let samples = [0.0,0.2,0.4,0.5,0.55,1.0]; // take these samples
let expected = [0.0,0.6,1.2,1.5,1.65,3.0];
for (value, result) in linear.sample(samples).zip(expected) {
assert_f64_near!(value, result);
}
// we can still use linear here as it was not consumed!
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.