polygonize OutlinePoints
authoralfadur
Sun, 04 Nov 2018 00:25:27 +0300
changeset 14145 6e0be42d0a8f
parent 14144 59ec51b78737
child 14146 376a0551b00a
polygonize OutlinePoints
rust/integral-geometry/src/lib.rs
rust/landgen/src/outline.rs
--- a/rust/integral-geometry/src/lib.rs	Sat Nov 03 23:19:28 2018 +0300
+++ b/rust/integral-geometry/src/lib.rs	Sun Nov 04 00:25:27 2018 +0300
@@ -383,8 +383,17 @@
         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 split_edge(&mut self, edge_index: usize, vertex: Point) {
+        self.vertices.insert(edge_index + 1, vertex);
+    }
+
+    pub fn iter<'a>(&'a self) -> impl Iterator<Item = &Point> + 'a {
+        (&self.vertices[..self.edges_count()]).iter()
+    }
+
+    pub fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item = &mut Point> + 'a {
+        let edges_count = self.edges_count();
+        (&mut self.vertices[..edges_count]).iter_mut()
     }
 
     pub fn iter_edges<'a>(&'a self) -> impl Iterator<Item = Line> + 'a {
--- a/rust/landgen/src/outline.rs	Sat Nov 03 23:19:28 2018 +0300
+++ b/rust/landgen/src/outline.rs	Sun Nov 04 00:25:27 2018 +0300
@@ -1,13 +1,15 @@
 use itertools::Itertools;
 use std::cmp::min;
 
-use integral_geometry::{Line, Point, Rect, Size};
+use integral_geometry::{
+    Line, Point, Rect, Size, Polygon
+};
 use land2d::Land2D;
 
 use outline_template::OutlineTemplate;
 
 pub struct OutlinePoints {
-    pub islands: Vec<Vec<Point>>,
+    pub islands: Vec<Polygon>,
     pub fill_points: Vec<Point>,
     pub size: Size,
     pub play_box: Rect,
@@ -37,7 +39,7 @@
                                 )
                                 + play_box.top_left()
                         })
-                        .collect()
+                        .collect::<Vec<_>>().into()
                 })
                 .collect(),
             fill_points: outline_template.fill_points.clone(),
@@ -45,13 +47,13 @@
     }
 
     pub fn total_len(&self) -> usize {
-        self.islands.iter().map(|i| i.len()).sum::<usize>() + self.fill_points.len()
+        self.islands.iter().map(|i| i.edges_count()).sum::<usize>() + self.fill_points.len()
     }
 
     pub fn iter(&self) -> impl Iterator<Item = &Point> {
         self.islands
             .iter()
-            .flat_map(|i| i.iter())
+            .flat_map(|p| p.iter())
             .chain(self.fill_points.iter())
     }
 
@@ -235,28 +237,10 @@
     ) {
         for is in 0..self.islands.len() {
             let mut i = 0;
-            let mut segment;
-
-            loop {
-                {
-                    let island = &self.islands[is];
-                    let mut end_point;
-                    if i < island.len() {
-                        end_point = if i + 1 < island.len() {
-                            island[i + 1]
-                        } else {
-                            island[0]
-                        };
-                    } else {
-                        break;
-                    }
-
-                    segment = Line::new(island[i], end_point);
-                }
-
-                if let Some(new_point) = self.divide_edge(segment, distance_divisor, random_numbers)
-                {
-                    self.islands[is].insert(i + 1, new_point);
+            while i < self.islands[is].edges_count() {
+                let segment = self.islands[is].get_edge(i);
+                if let Some(new_point) = self.divide_edge(segment, distance_divisor, random_numbers) {
+                    self.islands[is].split_edge(i, new_point);
                     i += 2;
                 } else {
                     i += 1;
@@ -288,12 +272,8 @@
         }
     }
 
-    fn segments_iter(&self) -> OutlineSegmentsIterator {
-        OutlineSegmentsIterator {
-            outline: self,
-            island: 0,
-            index: 0,
-        }
+    fn segments_iter<'a>(&'a self) -> impl Iterator<Item = Line> + 'a {
+        self.islands.iter().flat_map(|p| p.iter_edges())
     }
 
     pub fn mirror(&mut self) {
@@ -309,53 +289,14 @@
     }
 }
 
-struct OutlineSegmentsIterator<'a> {
-    outline: &'a OutlinePoints,
-    island: usize,
-    index: usize,
-}
-
-impl<'a> Iterator for OutlineSegmentsIterator<'a> {
-    type Item = Line;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        if self.island < self.outline.islands.len() {
-            if self.index + 1 < self.outline.islands[self.island].len() {
-                let result = Some(Line::new(
-                    self.outline.islands[self.island][self.index],
-                    self.outline.islands[self.island][self.index + 1],
-                ));
-
-                self.index += 1;
-
-                result
-            } else if self.index + 1 == self.outline.islands[self.island].len() {
-                let result = Some(Line::new(
-                    self.outline.islands[self.island][self.index],
-                    self.outline.islands[self.island][0],
-                ));
-
-                self.island += 1;
-                self.index = 0;
-
-                result
-            } else {
-                self.island += 1;
-                self.index = 0;
-                self.next()
-            }
-        } else {
-            None
-        }
-    }
-}
-
 #[test()]
 fn points_test() {
+    ;
     let mut points = OutlinePoints {
+
         islands: vec![
-            vec![Point::new(0, 0), Point::new(20, 0), Point::new(30, 30)],
-            vec![Point::new(10, 15), Point::new(15, 20), Point::new(20, 15)],
+            Polygon::new(&[Point::new(0, 0), Point::new(20, 0), Point::new(30, 30)]),
+            Polygon::new(&[Point::new(10, 15), Point::new(15, 20), Point::new(20, 15)]),
         ],
         fill_points: vec![Point::new(1, 1)],
         play_box: Rect::from_box(0, 100, 0, 100).with_margin(10),
@@ -374,5 +315,5 @@
 
     points.iter_mut().for_each(|p| p.x = 2);
     assert_eq!(points.fill_points[0].x, 2);
-    assert_eq!(points.islands[0][0].x, 2);
+    assert_eq!(points.islands[0].get_edge(0).start.x, 2);
 }