Trait Signal

Source
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§

Source

type Output

The element outputted

Required Methods§

Source

fn eval(&self, input: Input) -> Self::Output

Method to generate the element at the given input

Provided Methods§

Source

fn extract<I, J>(self, iterator: I) -> Extract<Self, J>
where Self: Sized, I: IntoIterator<IntoIter = J>, J: Iterator<Item = Input>,

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);
}
Source

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);
Source

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]);
Source

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.

Source

fn sample<I, J>(&self, iterator: I) -> Extract<&Self, J>
where Self: Sized, I: IntoIterator<IntoIter = J>, J: Iterator<Item = Input>,

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.

Implementations on Foreign Types§

Source§

impl<G: Signal<I> + ?Sized, I> Signal<I> for &G

Source§

type Output = <G as Signal<I>>::Output

Source§

fn eval(&self, input: I) -> Self::Output

Source§

impl<T: Copy> Signal<usize> for &[T]

Source§

type Output = T

Source§

fn eval(&self, input: usize) -> Self::Output

Source§

impl<T: Copy> Signal<usize> for Vec<T>

Source§

type Output = T

Source§

fn eval(&self, input: usize) -> Self::Output

Source§

impl<T: Copy, const N: usize> Signal<usize> for [T; N]

Source§

type Output = T

Source§

fn eval(&self, input: usize) -> Self::Output

Implementors§

Source§

impl<A, B, T> Signal<T> for Composite<A, B>
where A: Signal<T>, B: Signal<A::Output>,

Source§

type Output = <B as Signal<<A as Signal<T>>::Output>>::Output

Source§

impl<C> Signal<usize> for Sorted<C>
where C: Signal<usize>,

Source§

impl<F, R> Signal<R> for FuncEase<F>
where F: Fn(R) -> R,

Source§

impl<G> Signal<usize> for BorderBuffer<G>
where G: Chain,

Source§

impl<G> Signal<usize> for BorderDeletion<G>
where G: Chain,

Source§

impl<G> Signal<usize> for Repeat<G>
where G: Chain,

Source§

impl<G> Signal<usize> for Wrap<G>
where G: Chain,

Source§

impl<G, A, M, I> Signal<I> for TransformInput<G, A, M>
where I: Mul<M>, I::Output: Add<A>, A: Copy, M: Copy, G: Signal<<<I as Mul<M>>::Output as Add<A>>::Output>,

Source§

type Output = <G as Signal<<<I as Mul<M>>::Output as Add<A>>::Output>>::Output

Source§

impl<G, H, Input> Signal<Input> for Stack<G, H>
where G: Signal<Input>, H: Signal<Input>, Input: Copy,

Source§

type Output = (<G as Signal<Input>>::Output, <H as Signal<Input>>::Output)

Source§

impl<G, I> Signal<I> for Weighted<G>
where G: Signal<I>, G::Output: Project,

Source§

type Output = <<G as Signal<I>>::Output as Project>::Element

Source§

impl<G, Input> Signal<Input> for Weights<G>
where G: Signal<Input>, G::Output: IntoWeight,

Source§

type Output = Homogeneous<<<G as Signal<Input>>::Output as IntoWeight>::Element, <<G as Signal<Input>>::Output as IntoWeight>::Weight>

Source§

impl<G, R> Signal<R> for Clamp<G>
where G: Curve<R>, R: Real,

Source§

type Output = <G as Signal<R>>::Output

Source§

impl<G, R> Signal<R> for Slice<G, R>
where G: Signal<R>, R: Real,

Source§

type Output = <G as Signal<R>>::Output

Source§

impl<K, E, S, R> Signal<R> for BSpline<K, E, S>
where E: Chain, S: Space<E::Output>, E::Output: Merge<R> + Copy, R: Real + Debug, K: SortedChain<Output = R>,

Source§

impl<R> Signal<usize> for Equidistant<R>
where R: Real + FromPrimitive,

Source§

impl<R> Signal<R> for Identity

Source§

impl<R> Signal<R> for Plateau<R>
where R: Real + FromPrimitive,

Source§

impl<R, E, S> Signal<R> for Bezier<R, E, S>
where E: Chain, E::Output: Merge<R> + Copy, S: Space<E::Output>, R: Real,

Source§

impl<R, K, E, F> Signal<R> for Linear<K, E, F>
where K: SortedChain<Output = R>, E: Chain, E::Output: Merge<R> + Debug, F: Curve<R, Output = R>, R: Real + Debug,

Source§

impl<R, const N: usize> Signal<usize> for ConstEquidistant<R, N>
where R: Real + FromPrimitive,