Skip to main content

fastpack_core/algorithms/
polygon.rs

1use geo::{ConvexHull, MultiPoint, Point as GeoPoint};
2use image::RgbaImage;
3
4use crate::types::rect::Point;
5
6/// Compute the convex hull of all opaque pixels in `img`.
7///
8/// Vertices are in image-local pixel space (origin at the top-left of `img`).
9/// Returns an empty `Vec` when no pixels exceed `threshold`.
10pub fn compute_convex_hull(img: &RgbaImage, threshold: u8) -> Vec<Point> {
11    let geo_points: Vec<GeoPoint<f64>> = img
12        .enumerate_pixels()
13        .filter(|(_, _, pixel)| pixel[3] > threshold)
14        .map(|(x, y, _)| GeoPoint::new(x as f64, y as f64))
15        .collect();
16
17    if geo_points.is_empty() {
18        return Vec::new();
19    }
20
21    let hull = MultiPoint(geo_points).convex_hull();
22    hull.exterior()
23        .coords()
24        .map(|c| Point {
25            x: c.x as f32,
26            y: c.y as f32,
27        })
28        .collect()
29}