diff --git a/src/context.rs b/src/context.rs index cdc64eb..3e50f10 100644 --- a/src/context.rs +++ b/src/context.rs @@ -4,12 +4,12 @@ use geo::{polygon, LineString, MultiLineString, MultiPolygon, Polygon}; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; -use crate::context::commandline::Opt; +use crate::context::command_line_options::Opt; use crate::context::palette::Palette; use crate::context::renderer::{PngRenderContainer, RenderContainer, SvgRenderContainer}; use iso8601::Date::*; -pub mod commandline; +pub mod command_line_options; pub mod palette; pub mod renderer; @@ -116,6 +116,7 @@ impl Context { let opt = Opt::get_command_line_arguments(); let line_size = opt.line_size.clone(); + // todo : this is not correct let mm = 3.779527547619048; // calculated with inkscape 1587.40157 (px) / 420 (mm) (from a3) let (mut height, mut width) = match opt.format { None => (f64::from(opt.height.clone()), f64::from(opt.width.clone())), @@ -150,11 +151,12 @@ impl Context { let mut rng = StdRng::seed_from_u64(random_seed); // color - let y: f32 = rng.gen(); // generates a float between 0 and 1 - let hue: f32 = y * 360.0; - let saturation: f32 = f32::max(rng.gen(), 0.6); - let value: f32 = f32::max(rng.gen(), 0.6); - let palette = Palette::dark_on_bright(Palette::color(hue, saturation, value)); + let main_color = Palette::random_color(StdRng::seed_from_u64(rng.gen())); + let palette = match &opt.color_type[..] { + "bright_on_dark" => Palette::bright_on_dark(main_color), + "dark_on_bright" => Palette::dark_on_bright(main_color), + _ => Palette::bright_on_dark(main_color), + }; let render_container: Box = if opt.output_type == "svg" { let svg_surface = SvgSurface::new( diff --git a/src/context/commandline.rs b/src/context/command_line_options.rs similarity index 88% rename from src/context/commandline.rs rename to src/context/command_line_options.rs index b246a6c..de4cc1d 100644 --- a/src/context/commandline.rs +++ b/src/context/command_line_options.rs @@ -53,6 +53,14 @@ pub struct Opt { /// (must be ISO8601) #[structopt(long = "random-date", conflicts_with = "random-seed", parse(try_from_str = iso8601::date))] pub random_seed_date: Option, + + /// how to use color palette to draw image + #[structopt( + long, + possible_values=&["dark_on_bright", "bright_on_dark"], + default_value="dark_on_bright" + )] + pub color_type: String, } impl Opt { diff --git a/src/context/palette.rs b/src/context/palette.rs index ad486cc..4639f36 100644 --- a/src/context/palette.rs +++ b/src/context/palette.rs @@ -1,5 +1,6 @@ //! Color palate generator. +use crate::RandomExt; use palette::rgb::Rgb; use palette::FromColor; use palette::Hsl; @@ -19,21 +20,18 @@ impl Palette { /// and to color less. #[allow(dead_code)] pub fn random_color(mut rng: StdRng) -> Rgb { - //let mut rng = rand::thread_rng(); - let y: f32 = rng.gen(); // generates a float between 0 and 1 - let hue: f32 = y * 360.0; - let saturation: f32 = f32::max(rng.gen(), 0.6); - let value: f32 = f32::max(rng.gen(), 0.6); - //Rgb::from_linear(Hsv::new(hue, saturation, value).into_rgb()) + let hue: f32 = rng.gen_interval(0., 360.); + let saturation: f32 = rng.gen_interval(0.9, 1.0); + let value: f32 = rng.gen_interval(0.8, 1.0); Palette::color(hue, saturation, value) } + pub fn color(hue: f32, saturation: f32, value: f32) -> Rgb { Rgb::from_linear(Hsv::new(hue, saturation, value).into_rgb()) } /// generate a palette from the tint and shade palette - /// algorithm. choose a dark background and a bright filling color - #[allow(dead_code)] + /// algorithm. choose a dark background, and a bright filling color pub fn bright_on_dark(input: Rgb) -> Palette { let tint_and_shade_palette = TintAndShadePalette::create(input); Palette { @@ -43,7 +41,7 @@ impl Palette { } /// generate a palette from the tint and shade palette - /// algorithm. choose a bright background and a dark filling color + /// algorithm. choose a bright background, and a dark filling color pub fn dark_on_bright(input: Rgb) -> Palette { let tint_and_shade_palette = TintAndShadePalette::create(input); Palette { @@ -54,8 +52,7 @@ impl Palette { } /// The Tint and Shade Palette from https://gitlab.com/cameralibre/tint-and-shade -/// Thank you Sam -#[allow(dead_code)] +/// Thank you, Sam struct TintAndShadePalette { base_color: Rgb, base_tint_30: Rgb, diff --git a/src/extensions.rs b/src/extensions.rs index f2166c7..59b8478 100644 --- a/src/extensions.rs +++ b/src/extensions.rs @@ -1,3 +1,4 @@ pub(crate) mod merge_ext; +pub(crate) mod random_ext; pub(crate) mod scale_ext; pub(crate) mod translate_ext; diff --git a/src/extensions/random_ext.rs b/src/extensions/random_ext.rs new file mode 100644 index 0000000..8fe99c4 --- /dev/null +++ b/src/extensions/random_ext.rs @@ -0,0 +1,49 @@ +use rand::rngs::StdRng; +use rand::Rng; + +pub trait RandomExt { + fn gen_interval(&mut self, min: T, max: T) -> T; +} + +impl RandomExt for StdRng { + fn gen_interval(&mut self, min: f32, max: f32) -> f32 { + if min == max { + return min; + } + let minimum = f32::min(min, max); + let maximum = f32::max(min, max); + let diff = maximum - minimum; + let x: f32 = self.gen(); + x * diff + minimum + } +} + +impl RandomExt for StdRng { + fn gen_interval(&mut self, min: f64, max: f64) -> f64 { + if min == max { + return min; + } + let minimum = f64::min(min, max); + let maximum = f64::max(min, max); + let diff = maximum - minimum; + let x: f64 = self.gen(); + x * diff + minimum + } +} + +#[cfg(test)] +mod test { + use rand::prelude::StdRng; + use rand::{Rng, SeedableRng}; + + #[test] + fn test_gen() { + let random_seed = rand::random(); + let mut rng = StdRng::seed_from_u64(random_seed); + for _ in 0..1000 { + let random_number: f64 = rng.gen(); + assert!(random_number < 1.); + assert!(random_number > 0.); + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 6923347..8e23a7a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ pub use crate::context::Context; mod extensions; pub use crate::extensions::merge_ext::MergeExt; +pub use crate::extensions::random_ext::RandomExt; pub use crate::extensions::scale_ext::ScaleExt; pub use crate::extensions::translate_ext::TranslateExt;