ncollide_procedural 0.2.5

2 and 3-dimensional collision detection library in Rust: module for procedural generation of discrete geometric objects.
Documentation
use na::Norm;
use path::{PathSample, CurveSampler};
use polyline::Polyline;
use math::{Point, Vect};

/// A path with its sample points given by a polyline.
///
/// This will return sequencially each vertex of the polyline.
pub struct PolylinePath<'a, P: 'a + Point> {
    curr_len:               <P::Vect as Vect>::Scalar,
    curr_dir:               P::Vect,
    curr_pt_id:             usize,
    curr_pt:                P,
    polyline:               &'a Polyline<P>
}

impl<'a, P: Point> PolylinePath<'a, P> {
    /// Creates a new polyline-based path.
    pub fn new(polyline: &'a Polyline<P>) -> PolylinePath<'a, P> {
        assert!(polyline.coords.len() > 1, "The polyline must have at least two points.");

        let mut dir: P::Vect  = polyline.coords[1] - polyline.coords[0];
        let len: <P::Vect as Vect>::Scalar = dir.normalize_mut();

        PolylinePath {
            curr_len:   len,
            curr_dir:   dir,
            curr_pt_id: 0,
            curr_pt:    polyline.coords[0].clone(),
            polyline:   polyline
        }
    }
}

impl<'a, P> CurveSampler<P> for PolylinePath<'a, P>
    where P: Point {
    fn next(&mut self) -> PathSample<P> {
        let result =
            if self.curr_pt_id == 0 {
                PathSample::StartPoint(self.curr_pt.clone(), self.curr_dir.clone())
            }
            else if self.curr_pt_id < self.polyline.coords.len() - 1 {
                PathSample::InnerPoint(self.curr_pt.clone(), self.curr_dir.clone())
            }
            else if self.curr_pt_id == self.polyline.coords.len() - 1 {
                PathSample::EndPoint(self.curr_pt.clone(), self.curr_dir.clone())
            }
            else {
                PathSample::EndOfSample
            };

        self.curr_pt_id = self.curr_pt_id + 1;

        if self.curr_pt_id < self.polyline.coords.len() {
            self.curr_pt = self.polyline.coords[self.curr_pt_id].clone();

            if self.curr_pt_id < self.polyline.coords.len() - 1 {
                let mut curr_diff = self.polyline.coords[self.curr_pt_id + 1] -
                                    self.polyline.coords[self.curr_pt_id];
                self.curr_len = curr_diff.normalize_mut();
                self.curr_dir = curr_diff;
            }
        }

        result
    }
}