# HG changeset patch # User alfadur # Date 1541030122 -10800 # Node ID 9c817b2eedaef16dcc5f730697818eba6b0a4a77 # Parent 8a0d69c16cadea03e9e8cd1240f660fdedc2158c# Parent 0a75f54692cbc1c9d873c1f65d8fec5e1f7d4714 merge diff -r 0a75f54692cb -r 9c817b2eedae rust/integral-geometry/src/lib.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, diff -r 0a75f54692cb -r 9c817b2eedae rust/land2d/src/lib.rs --- 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 { pixels: vec2d::Vec2D, + play_size: Size, mask: SizeMask } impl Land2D { - 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 = Land2D::new(Size::new(32, 64), 0); + let l: Land2D = 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)); diff -r 0a75f54692cb -r 9c817b2eedae rust/landgen/Cargo.toml --- 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" diff -r 0a75f54692cb -r 9c817b2eedae rust/landgen/src/lib.rs --- 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 { zero: T, diff -r 0a75f54692cb -r 9c817b2eedae rust/landgen/src/template_based.rs --- 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>, + fill_points: Vec, + size: Size, +} + +impl OutlinePoints { + fn from_outline_template>( + 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 { + self.islands.iter_mut() + .flat_map(|i| i.iter_mut()) + .chain(self.fill_points.iter_mut()) + } + + fn distort>(&mut self, random_numbers: &mut I) { + unimplemented!() + } +} + struct OutlineTemplate { - islands: Vec>, + islands: Vec>, fill_points: Vec, 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, random_numbers: &mut I, ) -> Land2D { - 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); +}