use na::Norm;
use path::{PathSample, CurveSampler};
use polyline::Polyline;
use math::{Point, Vect};
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> {
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
}
}