rust/integral-geometry/src/lib.rs
changeset 14115 d0b0d61b7d5e
parent 14113 32a34bf70f65
child 14117 133f648c5fbd
--- a/rust/integral-geometry/src/lib.rs	Fri Nov 02 20:46:17 2018 +0300
+++ b/rust/integral-geometry/src/lib.rs	Fri Nov 02 21:30:48 2018 +0300
@@ -325,6 +325,51 @@
     }
 }
 
+pub struct Polygon {
+    vertices: Vec<Point>
+}
+
+impl Polygon {
+    pub fn new(vertices: &[Point]) -> Self {
+        let mut v = Vec::with_capacity(vertices.len() + 1);
+        v.extend_from_slice(vertices);
+        if !v.is_empty() {
+            let start = v[0];
+            v.push(start);
+        }
+        Self { vertices: v }
+    }
+
+    pub fn edges_count(&self) -> usize {
+        self.vertices.len() - 1
+    }
+
+    pub fn get_edge(&self, index: usize) -> Line {
+        Line::new(self.vertices[index], self.vertices[index + 1])
+    }
+
+    pub fn iter<'a>(&'a self) -> impl Iterator<Item = Point> + 'a {
+        (&self.vertices[..self.edges_count()]).iter().cloned()
+    }
+
+    pub fn iter_edges<'a>(&'a self) -> impl Iterator<Item = Line> + 'a {
+        (&self.vertices[0..self.edges_count()])
+            .iter()
+            .zip(&self.vertices[1..])
+            .map(|(s, e)| Line::new(*s, *e))
+    }
+}
+
+impl From<Vec<Point>> for Polygon {
+    fn from(mut v: Vec<Point>) -> Self {
+        if !v.is_empty() && v[0] != v[v.len() - 1] {
+            let start = v[0];
+            v.push(start)
+        }
+        Self { vertices: v }
+    }
+}
+
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 pub struct Line {
     pub start: Point,