bezier-nd 0.6.0

Bezier curve implementations using N-dimensional vectors
Documentation
//a Imports
use crate::Bezier;
use geo_nd::Float;

//a BezierLineIter
//tp BezierLineIter
/// An iterator with Item = (V, V) of straight lines that form a single Bezier curve
///
/// An iteration will provide (Pa, Pb) pairs of points, with
/// the next iteration providing (Pb, Pc), then (Pc, Pd), etc;
/// sharing the end/start points.
///
/// This iterator is generated by the [crate::Bezier::as_lines] method
pub struct BezierLineIter<F: Float, const D: usize> {
    /// Maximum curviness of the line segments returned
    straightness: F,
    /// A stack of future beziers to examine
    /// The top of the stack is p0->p1; below that is p1->p2, etc
    /// These beziers will need to be split to achieve the maximum
    /// curviness
    stack: Vec<Bezier<F, D>>,
}

//pi BezierLineIter
impl<F, const D: usize> BezierLineIter<F, D>
where
    F: Float,
{
    //fp new
    /// Create a new Bezier line iterator for a given Bezier and
    /// straightness
    ///
    /// This clones the Bezier.
    pub fn new(bezier: &Bezier<F, D>, straightness: F) -> Self {
        let stack = vec![*bezier];
        Self {
            straightness,
            stack,
        }
    }

    //zz All done
}

//ip Iterator for BezierLineIter
impl<F, const D: usize> Iterator for BezierLineIter<F, D>
where
    F: Float,
{
    /// Item is a pair of points that make a straight line
    type Item = ([F; D], [F; D]);
    /// next - return None or Some(pa,pb)
    ///
    /// It pops the first Bezier from the stack: this is (pa,px); if
    /// this is straight enough then return it, else split it in two
    /// (pa,pm), (pm,px) and push them in reverse order, then recurse.
    ///
    /// This forces the segment returned (eventually!) to be (pa,pb)
    /// and to leave the top of the stack starting with pb.
    fn next(&mut self) -> Option<Self::Item> {
        match self.stack.pop() {
            None => None,
            Some(b) => {
                if b.is_straight(self.straightness) {
                    Some(b.endpoints())
                } else {
                    let (b0, b1) = b.bisect();
                    self.stack.push(b1);
                    self.stack.push(b0);
                    self.next()
                }
            }
        }
    }

    //zz All done
}