use delaunator::{triangulate as delaunay, Point as DPoint};
use crate::Polygon;
pub fn triangulate(points: &[(i32, i32)]) -> Vec<Polygon> {
if points.len() < 3 {
return Vec::new();
}
let sites: Vec<DPoint> = points
.iter()
.map(|&(x, y)| DPoint {
x: x as f64,
y: y as f64,
})
.collect();
let tri = delaunay(&sites);
tri.triangles
.chunks_exact(3)
.filter_map(|t| {
let a = points.get(t[0])?;
let b = points.get(t[1])?;
let c = points.get(t[2])?;
Some(Polygon {
exterior: vec![*a, *b, *c],
holes: vec![],
})
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn triangulate_quad_gives_two_triangles() {
let pts = vec![(0, 0), (10, 0), (10, 10), (0, 10)];
let tris = triangulate(&pts);
assert_eq!(tris.len(), 2, "got {tris:?}");
}
#[test]
fn triangulate_under_three_returns_empty() {
assert!(triangulate(&[(0, 0), (1, 0)]).is_empty());
}
}