diff --git a/src/main.rs b/src/main.rs index 521bbe5..9c230f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,6 +46,8 @@ struct Args { #[clap(long)] char_swap: Option, #[clap(long)] + char_units: Option, + #[clap(long)] char_slices: Option, #[clap(long, value_enum)] colors: Vec, @@ -103,6 +105,7 @@ struct PatternConfig<'a> { shift: Option, invert: Option, swap: Option, + units: Option, slices: Option, } @@ -113,6 +116,7 @@ impl Args { Some(true), self.char_invert, self.char_swap, + self.char_units, self.char_slices, ) } @@ -123,6 +127,7 @@ impl Args { self.color_shift, self.color_invert, self.color_swap, + Some(1), self.color_slices, ) } @@ -176,6 +181,7 @@ impl<'a> PatternConfig<'a> { fn create(&self, rand: &mut impl Rng) -> Box { let mut pattern = self.create_base(rand); + let units = self.units.unwrap_or(rand.gen_range(1..=4)); let slices = self.slices.unwrap_or(rand.gen_range(1..=4)); if self.shift.unwrap_or(rand.gen()) { @@ -187,6 +193,9 @@ impl<'a> PatternConfig<'a> { if self.swap.unwrap_or(rand.gen()) { pattern = Box::new(SwapFactory::new(pattern)) } + if units != 1 { + pattern = Box::new(UnitsFactory::new(pattern, units)); + } if slices != 1 { pattern = Box::new(SliceFactory::new(pattern, slices)); } diff --git a/src/transform/mod.rs b/src/transform/mod.rs index 925e93a..3f5ebea 100644 --- a/src/transform/mod.rs +++ b/src/transform/mod.rs @@ -2,8 +2,10 @@ mod invert; mod shift; mod slice; mod swap; +mod units; pub use invert::*; pub use shift::*; pub use slice::*; pub use swap::*; +pub use units::*; diff --git a/src/transform/units.rs b/src/transform/units.rs new file mode 100644 index 0000000..4509ec6 --- /dev/null +++ b/src/transform/units.rs @@ -0,0 +1,32 @@ +use crate::pattern::*; +use crate::Vector; + +#[derive(derive_more::Constructor)] +pub struct UnitsFactory { + child: Box, + units: u8, +} + +#[derive(derive_more::Constructor)] +pub struct Units { + child: Box, + units: u8, +} + +impl PatternFactory for UnitsFactory { + fn create(&self, config: &Config) -> Box { + Box::new(Units::new(self.child.create(config), self.units)) + } +} + +impl Pattern for Units { + fn sample(&self, pos: Vector) -> f32 { + let sample = self.child.sample(pos); + + if 0.0 <= sample && sample < 1.0 { + (sample * self.units as f32) % 1.0 + } else { + sample + } + } +}