# HG changeset patch # User alfadur # Date 1540915552 -10800 # Node ID 2869c2ccb1b8dd17c16bc09e1f0ef5f551cf8a1b # Parent c47283feafacf4ddc31929b021682b8b00abe055 extract size struct for common usage diff -r c47283feafac -r 2869c2ccb1b8 rust/integral-geometry/src/lib.rs --- a/rust/integral-geometry/src/lib.rs Tue Oct 30 05:55:58 2018 +0300 +++ b/rust/integral-geometry/src/lib.rs Tue Oct 30 19:05:52 2018 +0300 @@ -45,6 +45,73 @@ } } +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct Size { + pub width: usize, + pub height: usize, +} + +impl Size { + #[inline] + pub fn new(width: usize, height: usize) -> Self { + Size { width, height } + } + + #[inline] + pub fn square(size: usize) -> Self { + Size { width: size, height: size } + } + + #[inline] + pub fn area(&self) -> usize { + self.width * self.height + } + + #[inline] + pub fn linear_index(&self, x: usize, y: usize) -> usize { + y * self.width + x + } + + #[inline] + pub fn is_power_of_two(&self) -> bool { + self.width.is_power_of_two() && self.height.is_power_of_two() + } + + #[inline] + pub fn to_mask(&self) -> SizeMask { + SizeMask::new(*self) + } +} + +pub struct SizeMask{ size: Size } + +impl SizeMask { + #[inline] + pub fn new(size: Size) -> Self { + assert!(size.is_power_of_two()); + let size = Size { + width: !(size.width - 1), + height: !(size.height - 1) + }; + SizeMask { size } + } + + #[inline] + pub fn contains_x>(&self, x: T) -> bool { + (self.size.width & x.into()) == 0 + } + + #[inline] + pub fn contains_y>(&self, y: T) -> bool { + (self.size.height & y.into()) == 0 + } + + #[inline] + pub fn contains(&self, point: Point) -> bool { + self.contains_x(point.x as usize) && self.contains_y(point.y as usize) + } +} + macro_rules! bin_op_impl { ($op: ty, $name: tt) => { impl $op for Point { diff -r c47283feafac -r 2869c2ccb1b8 rust/land2d/src/lib.rs --- a/rust/land2d/src/lib.rs Tue Oct 30 05:55:58 2018 +0300 +++ b/rust/land2d/src/lib.rs Tue Oct 30 19:05:52 2018 +0300 @@ -4,23 +4,21 @@ use std::cmp; use std::ops; -use integral_geometry::{ArcPoints, EquidistantPoints, LinePoints, Point}; +use integral_geometry::{ + ArcPoints, EquidistantPoints, LinePoints, + Point, Size, SizeMask +}; pub struct Land2D { pixels: vec2d::Vec2D, - width_mask: usize, - height_mask: usize, + mask: SizeMask } impl Land2D { - pub fn new(width: usize, height: usize, fill_value: T) -> Self { - assert!(width.is_power_of_two()); - assert!(height.is_power_of_two()); - + pub fn new(size: Size, fill_value: T) -> Self { Self { - pixels: vec2d::Vec2D::new(width, height, fill_value), - width_mask: !(width - 1), - height_mask: !(height - 1), + pixels: vec2d::Vec2D::new(size, fill_value), + mask: size.to_mask() } } @@ -36,12 +34,12 @@ #[inline] pub fn is_valid_x(&self, x: i32) -> bool { - (x as usize & self.width_mask) == 0 + self.mask.contains_x(x as usize) } #[inline] pub fn is_valid_y(&self, y: i32) -> bool { - (y as usize & self.height_mask) == 0 + self.mask.contains_y(y as usize) } #[inline] @@ -269,7 +267,7 @@ #[test] fn basics() { - let l: Land2D = Land2D::new(32, 64, 0); + let l: Land2D = Land2D::new(Size::new(32, 64), 0); assert!(l.is_valid_coordinate(0, 0)); assert!(!l.is_valid_coordinate(-1, -1)); @@ -281,7 +279,7 @@ #[test] fn fill() { - let mut l: Land2D = Land2D::new(128, 128, 0); + let mut l: Land2D = Land2D::new(Size::square(128), 0); l.draw_line(Point::new(0, 0), Point::new(32, 96), 1); l.draw_line(Point::new(32, 96), Point::new(64, 32), 1); diff -r c47283feafac -r 2869c2ccb1b8 rust/landgen/src/template_based.rs --- a/rust/landgen/src/template_based.rs Tue Oct 30 05:55:58 2018 +0300 +++ b/rust/landgen/src/template_based.rs Tue Oct 30 19:05:52 2018 +0300 @@ -1,4 +1,4 @@ -use integral_geometry::Point; +use integral_geometry::{Point, Size}; use land2d::Land2D; use LandGenerationParameters; use LandGenerator; @@ -6,8 +6,7 @@ struct OutlineTemplate { islands: Vec>, fill_points: Vec, - width: usize, - height: usize, + size: Size, can_flip: bool, can_invert: bool, can_mirror: bool, @@ -45,8 +44,7 @@ } let mut land = Land2D::new( - self.outline_template.width, - self.outline_template.height, + self.outline_template.size, parameters.basic, ); diff -r c47283feafac -r 2869c2ccb1b8 rust/vec2d/Cargo.toml --- a/rust/vec2d/Cargo.toml Tue Oct 30 05:55:58 2018 +0300 +++ b/rust/vec2d/Cargo.toml Tue Oct 30 19:05:52 2018 +0300 @@ -4,3 +4,4 @@ authors = ["Andrey Korotaev "] [dependencies] +integral-geometry = { path = "../integral-geometry" } diff -r c47283feafac -r 2869c2ccb1b8 rust/vec2d/src/lib.rs --- a/rust/vec2d/src/lib.rs Tue Oct 30 05:55:58 2018 +0300 +++ b/rust/vec2d/src/lib.rs Tue Oct 30 19:05:52 2018 +0300 @@ -1,10 +1,12 @@ +extern crate integral_geometry; + use std::ops::{Index, IndexMut}; use std::slice::SliceIndex; +use integral_geometry::Size; pub struct Vec2D { data: Vec, - width: usize, - height: usize, + size: Size, } impl Index for Vec2D { @@ -12,67 +14,70 @@ #[inline] fn index(&self, row: usize) -> &[T] { - debug_assert!(row < self.height); + debug_assert!(row < self.height()); - let pos = row * self.width; + let pos = row * self.width(); - &self.data[pos..pos + self.width] + &self.data[pos..pos + self.width()] } } impl IndexMut for Vec2D { #[inline] fn index_mut(&mut self, row: usize) -> &mut [T] { - debug_assert!(row < self.height); + debug_assert!(row < self.height()); - let pos = row * self.width; + let pos = row * self.width(); - &mut self.data[pos..pos + self.width] + &mut self.data[pos..pos + self.size.width] } } -impl Vec2D { - pub fn new(width: usize, height: usize, value: T) -> Self { - Self { - data: vec![value; width * height], - width, - height, - } - } - +impl Vec2D { #[inline] pub fn width(&self) -> usize { - self.width + self.size.width } #[inline] pub fn height(&self) -> usize { - self.height + self.size.height + } + + #[inline] + pub fn size(&self) -> Size { + self.size + } +} + +impl Vec2D { + pub fn new(size: Size, value: T) -> Self { + Self { size, data: vec![value; size.area()] } } #[inline] pub fn get(&self, row: usize, column: usize) -> Option<&>::Output> { - self.data.get(row * self.width + column) + self.data.get(row * self.width() + column) } #[inline] pub fn get_mut(&mut self, row: usize, column: usize) -> Option<&mut >::Output> { - self.data.get_mut(row * self.width + column) + self.data.get_mut(row * self.size.width + column) } #[inline] pub unsafe fn get_unchecked(&self, row: usize, column: usize) -> &>::Output { - self.data.get_unchecked(row * self.width + column) + self.data.get_unchecked(row * self.width() + column) } #[inline] pub unsafe fn get_unchecked_mut(&mut self, row: usize, column: usize) -> &mut >::Output { - self.data.get_unchecked_mut(row * self.width + column) + self.data.get_unchecked_mut(row * self.size.width + column) } #[inline] pub fn rows(&self) -> impl Iterator { - self.data.chunks(self.width) + self.data.chunks(self.width()) } } @@ -82,10 +87,10 @@ #[test] fn basics() { - let mut v: Vec2D = Vec2D::new(2, 3, 0xff); + let mut v: Vec2D = Vec2D::new(Size::new(2, 3), 0xff); - assert_eq!(v.width, 2); - assert_eq!(v.height, 3); + assert_eq!(v.width(), 2); + assert_eq!(v.height(), 3); assert_eq!(v[0][0], 0xff); assert_eq!(v[2][1], 0xff);