polysplit 0.1.0

Algorithm that allows to split polylines into segments by the defined list of points not necessary belonging to the polyline
Documentation
use crate::polysplit::{PolySplit, CutRatioResult, DistanceToSegmentResult};

#[derive(Clone, Copy, Debug)]
pub struct Point(pub f64, pub f64);

impl Point {
    pub fn distance_to(&self, to: &Point) -> f64 {
        ((self.0 - to.0).powf(2.0) + (self.1 - to.1).powf(2.0)).sqrt()
    }
}

impl PolySplit<f64> for Point {
    fn distance_to_point(&self, point: &Self) -> f64 {
        return self.distance_to(point);
    }

    fn distance_to_segment(&self, s: (&Point, &Point)) -> DistanceToSegmentResult<Point, f64> {
        let segment_distance = s.0.distance_to(s.1);
        if segment_distance < 1e-9 {
            let distance = self.distance_to(s.0);
            return DistanceToSegmentResult{
                distance,
                cut_point: *s.0,
                cut_ratio: CutRatioResult::Begin,
            };
        }

        let vx = s.1.0 - s.0.0;
        let vy = s.1.1 - s.0.1;

        let ux = self.0 - s.0.0;
        let uy = self.1 - s.0.1;

        let ratio = (ux*vx+uy*vy)/(vx*vx+vy*vy);
        let cut_ratio = ratio.min(1.0).max(0.0);

        if cut_ratio <= 0.0 {
            let distance = self.distance_to(s.0);

            DistanceToSegmentResult{
                distance,
                cut_point: *s.0,
                cut_ratio: CutRatioResult::Begin,
            }
        } else if cut_ratio >= 1.0 {
            let distance = self.distance_to(s.1);

            DistanceToSegmentResult{
                distance,
                cut_point: *s.1,
                cut_ratio: CutRatioResult::End,
            }
        } else {
            let x = s.0.0 + cut_ratio * vx;
            let y = s.0.1 + cut_ratio * vy;
            let cut_point = Point(x, y);
            let distance = self.distance_to(&cut_point);

            DistanceToSegmentResult{
                distance,
                cut_point,
                cut_ratio: CutRatioResult::Medium(cut_ratio),
            }
        }
    }
}