use rand::{Rng, distr::uniform::SampleRange, seq::IndexedRandom}; use crate::{LineSegment, Object, Point, Region, Shape}; impl Shape { pub fn random_starting_at( rng: &mut R, start: Point, region: &Region, line_width: f32, polygon_vertices_range: impl SampleRange, ) -> Self { match rng.random_range(1..=7) { 1 => Self::random_polygon(rng, region, polygon_vertices_range), 2 => Self::BigCircle(start), 3 => Self::BigDot(start), 4 => Self::Dot(start), 5 => Self::CurveInward( start, region.random_end(rng, start), line_width, ), 6 => Self::CurveOutward( start, region.random_end(rng, start), line_width, ), 7 => Self::Line( Point::random(rng, region), Point::random(rng, region), line_width, ), _ => unreachable!(), } } pub fn random_polygon( rng: &mut R, region: &Region, vertices_range: impl SampleRange, ) -> Shape { let number_of_anchors = rng.random_range(vertices_range); let start = Point::random(rng, region); let mut lines: Vec = vec![]; for _ in 0..number_of_anchors { let next_anchor = Point::random(rng, region); lines.push(Self::random_line_segment(rng, next_anchor)); } Shape::Polygon(start, lines) } pub fn random_line_segment( rng: &mut R, end: Point, ) -> LineSegment { match rng.random_range(1..=3) { 1 => LineSegment::Straight(end), 2 => LineSegment::InwardCurve(end), 3 => LineSegment::OutwardCurve(end), _ => unreachable!(), } } pub fn random( rng: &mut impl Rng, region: &Region, line_width: f32, polygon_vertices_range: impl SampleRange, ) -> Shape { let start = Point::random(rng, region); Shape::random_starting_at( rng, start, region, line_width, polygon_vertices_range, ) } pub fn random_curve_within( rng: &mut impl Rng, region: &Region, line_width: f32, ) -> Shape { let start = region.random_point(rng); match rng.random_range(1..=3) { 1 => Shape::CurveInward( start, region.random_end(rng, start), line_width, ), 2 => Shape::CurveOutward( start, region.random_end(rng, start), line_width, ), 3 => Shape::Line( Point::random(rng, region), Point::random(rng, region), line_width, ), _ => unreachable!(), } } } impl Object { pub fn flickering(self, rng: &mut impl Rng, amplitude: f32) -> Self { self.opacified(rng.random_range((1.0 - amplitude).max(0.0)..1.0)) } pub fn pick_random_tag( &mut self, rng: &mut R, tags: &[&str], ) -> String { self.tag(tags.choose(rng).expect("Coudln't choose tag")) } }