Implement OutlinePoints for land generators, some ground work for template based landgen
--- a/rust/integral-geometry/src/lib.rs Mon Oct 29 23:06:18 2018 +0100
+++ b/rust/integral-geometry/src/lib.rs Wed Oct 31 23:36:05 2018 +0100
@@ -73,6 +73,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/landgen/Cargo.toml Mon Oct 29 23:06:18 2018 +0100
+++ b/rust/landgen/Cargo.toml Wed Oct 31 23:36:05 2018 +0100
@@ -6,3 +6,4 @@
[dependencies]
integral-geometry = { path = "../integral-geometry" }
land2d = { path = "../land2d" }
+itertools = "0.7.8"
--- a/rust/landgen/src/lib.rs Mon Oct 29 23:06:18 2018 +0100
+++ b/rust/landgen/src/lib.rs Wed Oct 31 23:36:05 2018 +0100
@@ -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 Mon Oct 29 23:06:18 2018 +0100
+++ b/rust/landgen/src/template_based.rs Wed Oct 31 23:36:05 2018 +0100
@@ -1,10 +1,59 @@
+use itertools::Itertools;
+
use integral_geometry::Point;
+use integral_geometry::Rect;
use land2d::Land2D;
use LandGenerationParameters;
use LandGenerator;
+struct OutlinePoints {
+ islands: Vec<Vec<Point>>,
+ fill_points: Vec<Point>,
+ width: usize,
+ height: usize,
+}
+
+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(),
+ width: outline_template.width,
+ height: outline_template.height,
+ }
+ }
+
+ fn for_each<F: Fn(&mut Point)>(&mut self, f: F) {
+ self.islands
+ .iter_mut()
+ .flat_map(|i| i.iter_mut())
+ .chain(self.fill_points.iter_mut())
+ .into_iter()
+ .for_each(f);
+ }
+
+ 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>,
width: usize,
height: usize,
@@ -18,10 +67,8 @@
outline_template: OutlineTemplate,
}
-impl OutlineTemplate {}
-
impl TemplatedLandGenerator {
- fn new(outline_template: OutlineTemplate) -> Self {
+ pub fn new(outline_template: OutlineTemplate) -> Self {
Self { outline_template }
}
}
@@ -32,24 +79,62 @@
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.width, points.height, 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.width = land.width();
+ points.height = land.height();
+
+ points.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.for_each(|p| p.x = land.width() as i32 - 1 - p.x);
+ }
}
-
- pa.push(island_points);
}
- let mut land = Land2D::new(
- self.outline_template.width,
- self.outline_template.height,
- parameters.basic,
- );
+ // flip
+ if self.outline_template.can_flip {
+ if let Some(b) = random_numbers.next() {
+ if b & 1 != 0 {
+ points.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)],
+ width: 100,
+ height: 100,
+ };
+
+ points.for_each(|p| p.x = 2);
+ assert_eq!(points.fill_points[0].x, 2);
+}