rcgal 0.2.2

Rust Computational Geometry Algorithms Library.
Documentation
use crate::kernel::{number_type::NumberType, point_2::Point2};

pub struct ConvexHull2<T: NumberType> {
    pub points: Vec<Point2<T>>,
}

impl<T: NumberType> ConvexHull2<T> {
    pub fn new(points: Vec<Point2<T>>) -> Self {
        Self { points }
    }

    pub fn convex_hull(&mut self) -> Vec<Point2<T>> {
        self.points.sort_by(|a, b| {
            if !a.x().equals(b.x()) {
                a.x().partial_cmp(&b.x()).unwrap()
            } else {
                a.y().partial_cmp(&b.y()).unwrap()
            }
        });
        let mut lower: Vec<Point2<T>> = vec![];
        let mut upper: Vec<Point2<T>> = vec![];
        for p in self.points.iter() {
            while lower.len() >= 2
                && Self::cross(&lower[lower.len() - 2], &lower[lower.len() - 1], &p) <= T::zero()
            {
                lower.pop();
            }
            lower.push(p.clone());
        }
        for p in self.points.iter().rev() {
            while upper.len() >= 2
                && Self::cross(&upper[upper.len() - 2], &upper[upper.len() - 1], &p) <= T::zero()
            {
                upper.pop();
            }
            upper.push(p.clone());
        }
        lower.pop();
        upper.pop();
        lower.extend(upper);
        lower
    }

    fn cross(a: &Point2<T>, b: &Point2<T>, c: &Point2<T>) -> T {
        (b.x() - a.x()) * (c.y() - a.y()) - (b.y() - a.y()) * (c.x() - a.x())
    }
}