vdtfont/delaunay/
polygon.rs

1use super::DelaunayTriangleHandle;
2
3use crate::point::Point;
4use crate::point::PointHandle;
5
6use std::collections::HashSet;
7use std::convert;
8
9/// A set of points.
10pub struct Polygon<'arena> {
11    points: Vec<PointHandle<'arena>>,
12}
13
14impl<'arena> Polygon<'arena> {
15    /// Creates a new [`Polygon`] from the given points.
16    pub fn new(points: Vec<PointHandle<'arena>>) -> Self {
17        Self { points }
18    }
19
20    /// Creates a new [`Polygon`] from the vertices of the given triangles.
21    pub fn from_triangles(triangles: &[DelaunayTriangleHandle<'arena>]) -> Self {
22        triangles
23            .iter()
24            .flat_map(|t| t.points())
25            .collect::<HashSet<PointHandle>>()
26            .into_iter()
27            .collect::<Vec<PointHandle>>()
28            .into()
29    }
30
31    /// Returns a reference to the points in the polygon.
32    pub fn points(&self) -> &Vec<PointHandle<'arena>> {
33        &self.points
34    }
35
36    /// Sorts the points in the polygon with the origin at `origin` by angle.
37    pub fn sort_by_angle(&mut self, origin: PointHandle<'arena>) {
38        self.points.sort_by(|a, b| {
39            let a = Point::new(a.x() - origin.x(), a.y() - origin.y());
40            let b = Point::new(b.x() - origin.x(), b.y() - origin.y());
41
42            libm::atan2f(a.y(), a.x())
43                .partial_cmp(&libm::atan2f(b.y(), b.x()))
44                .unwrap()
45        });
46    }
47}
48
49impl<'arena> convert::From<Vec<PointHandle<'arena>>> for Polygon<'arena> {
50    fn from(points: Vec<PointHandle<'arena>>) -> Self {
51        Self::new(points)
52    }
53}
54
55impl<'arena> convert::From<Vec<DelaunayTriangleHandle<'arena>>> for Polygon<'arena> {
56    fn from(triangles: Vec<DelaunayTriangleHandle<'arena>>) -> Self {
57        Self::from_triangles(&triangles)
58    }
59}
60
61impl<'arena> convert::From<&Vec<DelaunayTriangleHandle<'arena>>> for Polygon<'arena> {
62    fn from(triangles: &Vec<DelaunayTriangleHandle<'arena>>) -> Self {
63        Self::from_triangles(triangles)
64    }
65}
66
67impl<'arena> convert::From<Polygon<'arena>> for Vec<PointHandle<'arena>> {
68    fn from(polygon: Polygon<'arena>) -> Self {
69        polygon.points
70    }
71}