1use crate::{ParametricPath, Path, Scalar};
10
11pub fn equidistant<P: Path>(
16 path: &P,
17 step: P::Scalar,
18) -> impl Iterator<Item = Result<P::Point, P::Error>> + '_ {
19 let length = path.length();
20 let zero = P::Scalar::zero();
21 let mut s = zero;
22 core::iter::from_fn(move || {
23 if s > length {
24 None
25 } else {
26 let result = path.sample_at(s);
27 s = s + step;
28 Some(result)
29 }
30 })
31}
32
33pub fn n_samples<P: Path>(
38 path: &P,
39 n: usize,
40) -> impl Iterator<Item = Result<P::Point, P::Error>> + '_ {
41 let length = path.length();
42 let zero = P::Scalar::zero();
43 let one = P::Scalar::one();
44 let n_scalar = P::Scalar::from_usize(n);
45 let step = if n > 1 {
46 length / (n_scalar - one)
47 } else {
48 zero
49 };
50 (0..n).map(move |i| {
51 let s = if n == 1 {
52 zero
53 } else {
54 P::Scalar::from_usize(i) * step
55 };
56 path.sample_at(s)
57 })
58}
59
60pub fn uniform_t<P: ParametricPath>(
65 path: &P,
66 n: usize,
67) -> impl Iterator<Item = Result<P::Point, P::Error>> + '_ {
68 let zero = P::Scalar::zero();
69 let one = P::Scalar::one();
70 let n_scalar = P::Scalar::from_usize(n);
71 let dt = if n > 1 { one / (n_scalar - one) } else { zero };
72 (0..n).map(move |i| {
73 let t = if n == 1 {
74 zero
75 } else {
76 P::Scalar::from_usize(i) * dt
77 };
78 path.sample_t(t)
79 })
80}