merge
authoralfadur
Thu, 01 Nov 2018 02:55:22 +0300
changeset 14052 9c817b2eedae
parent 14051 8a0d69c16cad (diff)
parent 14049 0a75f54692cb (current diff)
child 14053 38eb5937169e
merge
rust/integral-geometry/src/lib.rs
rust/land2d/src/lib.rs
rust/landgen/src/template_based.rs
--- a/rust/integral-geometry/src/lib.rs	Wed Oct 31 22:41:05 2018 +0300
+++ b/rust/integral-geometry/src/lib.rs	Thu Nov 01 02:55:22 2018 +0300
@@ -78,6 +78,14 @@
     }
 
     #[inline]
+    pub fn next_power_of_two(&self) -> Self {
+        Self {
+            width: self.width.next_power_of_two(),
+            height: self.height.next_power_of_two()
+        }
+    }
+
+    #[inline]
     pub fn to_mask(&self) -> SizeMask {
         SizeMask::new(*self)
     }
@@ -146,6 +154,22 @@
 bin_assign_op_impl!(MulAssign, mul_assign);
 bin_assign_op_impl!(DivAssign, div_assign);
 
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+pub struct Rect {
+    pub x: i32,
+    pub y: i32,
+    pub width: u32,
+    pub height: u32,
+}
+
+impl Rect {
+    #[inline]
+    pub fn new(x: i32, y: i32, width: u32, height: u32) -> Self {
+        Self { x, y, width, height }
+    }
+}
+
+
 pub struct LinePoints {
     accumulator: Point,
     direction: Point,
--- a/rust/land2d/src/lib.rs	Wed Oct 31 22:41:05 2018 +0300
+++ b/rust/land2d/src/lib.rs	Thu Nov 01 02:55:22 2018 +0300
@@ -2,7 +2,6 @@
 extern crate vec2d;
 
 use std::cmp;
-use std::ops;
 
 use integral_geometry::{
     ArcPoints, EquidistantPoints, LinePoints,
@@ -11,14 +10,17 @@
 
 pub struct Land2D<T> {
     pixels: vec2d::Vec2D<T>,
+    play_size: Size,
     mask: SizeMask
 }
 
 impl<T: Copy + PartialEq> Land2D<T> {
-    pub fn new(size: Size, fill_value: T) -> Self {
+    pub fn new(play_size: Size, fill_value: T) -> Self {
+        let real_size = play_size.next_power_of_two();
         Self {
-            pixels: vec2d::Vec2D::new(size, fill_value),
-            mask: size.to_mask()
+            play_size,
+            pixels: vec2d::Vec2D::new(real_size, fill_value),
+            mask: real_size.to_mask()
         }
     }
 
@@ -33,6 +35,26 @@
     }
 
     #[inline]
+    pub fn size(&self) -> Size {
+        self.pixels.size()
+    }
+
+    #[inline]
+    pub fn play_width(&self) -> usize {
+        self.play_size.width
+    }
+
+    #[inline]
+    pub fn play_height(&self) -> usize {
+        self.play_size.height
+    }
+
+    #[inline]
+    pub fn play_size(&self) -> Size {
+        self.play_size
+    }
+
+    #[inline]
     pub fn is_valid_x(&self, x: i32) -> bool {
         self.mask.contains_x(x as usize)
     }
@@ -267,7 +289,12 @@
 
     #[test]
     fn basics() {
-        let l: Land2D<u8> = Land2D::new(Size::new(32, 64), 0);
+        let l: Land2D<u8> = Land2D::new(Size::new(30, 50), 0);
+
+        assert_eq!(l.play_width(), 30);
+        assert_eq!(l.play_height(), 50);
+        assert_eq!(l.width(), 32);
+        assert_eq!(l.height(), 64);
 
         assert!(l.is_valid_coordinate(0, 0));
         assert!(!l.is_valid_coordinate(-1, -1));
--- a/rust/landgen/Cargo.toml	Wed Oct 31 22:41:05 2018 +0300
+++ b/rust/landgen/Cargo.toml	Thu Nov 01 02:55:22 2018 +0300
@@ -6,3 +6,4 @@
 [dependencies]
 integral-geometry = { path = "../integral-geometry" }
 land2d = { path = "../land2d" }
+itertools = "0.7.8"
--- a/rust/landgen/src/lib.rs	Wed Oct 31 22:41:05 2018 +0300
+++ b/rust/landgen/src/lib.rs	Thu Nov 01 02:55:22 2018 +0300
@@ -2,6 +2,7 @@
 
 extern crate integral_geometry;
 extern crate land2d;
+extern crate itertools;
 
 pub struct LandGenerationParameters<T> {
     zero: T,
--- a/rust/landgen/src/template_based.rs	Wed Oct 31 22:41:05 2018 +0300
+++ b/rust/landgen/src/template_based.rs	Thu Nov 01 02:55:22 2018 +0300
@@ -1,10 +1,53 @@
-use integral_geometry::{Point, Size};
+use itertools::Itertools;
+
+use integral_geometry::{Point, Size, Rect};
 use land2d::Land2D;
 use LandGenerationParameters;
 use LandGenerator;
 
+struct OutlinePoints {
+    islands: Vec<Vec<Point>>,
+    fill_points: Vec<Point>,
+    size: Size,
+}
+
+impl OutlinePoints {
+    fn from_outline_template<I: Iterator<Item = u32>>(
+        outline_template: &OutlineTemplate,
+        random_numbers: &mut I,
+    ) -> Self {
+        Self {
+            islands: outline_template
+                .islands
+                .iter()
+                .map(|i| {
+                    i.iter()
+                        .zip(random_numbers.tuples())
+                        .map(|(rect, (rnd_a, rnd_b))| {
+                            Point::new(
+                                rect.x + (rnd_a % rect.width) as i32,
+                                rect.y + (rnd_b % rect.height) as i32,
+                            )
+                        }).collect()
+                }).collect(),
+            fill_points: outline_template.fill_points.clone(),
+            size: outline_template.size
+        }
+    }
+
+    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Point> {
+        self.islands.iter_mut()
+            .flat_map(|i| i.iter_mut())
+            .chain(self.fill_points.iter_mut())
+    }
+
+    fn distort<I: Iterator<Item = u32>>(&mut self, random_numbers: &mut I) {
+        unimplemented!()
+    }
+}
+
 struct OutlineTemplate {
-    islands: Vec<Vec<Point>>,
+    islands: Vec<Vec<Rect>>,
     fill_points: Vec<Point>,
     size: Size,
     can_flip: bool,
@@ -17,10 +60,8 @@
     outline_template: OutlineTemplate,
 }
 
-impl OutlineTemplate {}
-
 impl TemplatedLandGenerator {
-    fn new(outline_template: OutlineTemplate) -> Self {
+    pub fn new(outline_template: OutlineTemplate) -> Self {
         Self { outline_template }
     }
 }
@@ -31,23 +72,61 @@
         parameters: LandGenerationParameters<T>,
         random_numbers: &mut I,
     ) -> Land2D<T> {
-        let mut pa = Vec::new();
+        let mut points =
+            OutlinePoints::from_outline_template(&self.outline_template, random_numbers);
+
+        let mut land = Land2D::new(points.size, parameters.basic);
 
-        for island in &self.outline_template.islands {
-            let mut island_points = Vec::new();
+        let top_left = Point::new(
+            (land.width() - land.play_width() / 2) as i32,
+            (land.height() - land.play_height()) as i32,
+        );
 
-            for p in island {
-                island_points.push(p);
+        points.size = land.size();
+
+        points.iter_mut().for_each(|p| *p += top_left);
+
+        // mirror
+        if self.outline_template.can_mirror {
+            if let Some(b) = random_numbers.next() {
+                if b & 1 != 0 {
+                    points.iter_mut().for_each(|p| p.x = land.width() as i32 - 1 - p.x);
+                }
             }
-
-            pa.push(island_points);
         }
 
-        let mut land = Land2D::new(
-            self.outline_template.size,
-            parameters.basic,
-        );
+        // flip
+        if self.outline_template.can_flip {
+            if let Some(b) = random_numbers.next() {
+                if b & 1 != 0 {
+                    points.iter_mut().for_each(|p|
+                        p.y = land.height() as i32 - 1 - p.y);
+                }
+            }
+        }
+
+        points.distort(random_numbers);
+
+        // draw_edge(points, land, parameters.zero)
+
+        for p in points.fill_points {
+            land.fill(p, parameters.zero, parameters.zero)
+        }
+
+        // draw_edge(points, land, parameters.basic)
 
         land
     }
 }
+
+#[test()]
+fn points_test() {
+    let mut points = OutlinePoints {
+        islands: vec![vec![]],
+        fill_points: vec![Point::new(1, 1)],
+        size: Size::square(100)
+    };
+
+    points.iter_mut().for_each(|p| p.x = 2);
+    assert_eq!(points.fill_points[0].x, 2);
+}