use crate::{ParametricPath, Path, Scalar};
pub fn equidistant<P: Path>(
path: &P,
step: P::Scalar,
) -> impl Iterator<Item = Result<P::Point, P::Error>> + '_ {
let length = path.length();
let zero = P::Scalar::zero();
let mut s = zero;
core::iter::from_fn(move || {
if s > length {
None
} else {
let result = path.sample_at(s);
s = s + step;
Some(result)
}
})
}
pub fn n_samples<P: Path>(
path: &P,
n: usize,
) -> impl Iterator<Item = Result<P::Point, P::Error>> + '_ {
let length = path.length();
let zero = P::Scalar::zero();
let one = P::Scalar::one();
let n_scalar = P::Scalar::from_usize(n);
let step = if n > 1 {
length / (n_scalar - one)
} else {
zero
};
(0..n).map(move |i| {
let s = if n == 1 {
zero
} else {
P::Scalar::from_usize(i) * step
};
path.sample_at(s)
})
}
pub fn uniform_t<P: ParametricPath>(
path: &P,
n: usize,
) -> impl Iterator<Item = Result<P::Point, P::Error>> + '_ {
let zero = P::Scalar::zero();
let one = P::Scalar::one();
let n_scalar = P::Scalar::from_usize(n);
let dt = if n > 1 { one / (n_scalar - one) } else { zero };
(0..n).map(move |i| {
let t = if n == 1 {
zero
} else {
P::Scalar::from_usize(i) * dt
};
path.sample_t(t)
})
}