experimental SVG-based video rendering engine made for music videos. React to MIDI or arbitrary signals from your DAW through "probe" VSTs
at main 3.4 kB view raw
1use rand::{Rng, distr::uniform::SampleRange, seq::IndexedRandom}; 2 3use crate::{LineSegment, Object, Point, Region, Shape}; 4 5impl Shape { 6 pub fn random_starting_at<R: rand::Rng>( 7 rng: &mut R, 8 start: Point, 9 region: &Region, 10 line_width: f32, 11 polygon_vertices_range: impl SampleRange<usize>, 12 ) -> Self { 13 match rng.random_range(1..=7) { 14 1 => Self::random_polygon(rng, region, polygon_vertices_range), 15 2 => Self::BigCircle(start), 16 3 => Self::BigDot(start), 17 4 => Self::Dot(start), 18 5 => Self::CurveInward( 19 start, 20 region.random_end(rng, start), 21 line_width, 22 ), 23 6 => Self::CurveOutward( 24 start, 25 region.random_end(rng, start), 26 line_width, 27 ), 28 7 => Self::Line( 29 Point::random(rng, region), 30 Point::random(rng, region), 31 line_width, 32 ), 33 _ => unreachable!(), 34 } 35 } 36 37 pub fn random_polygon<R: rand::Rng>( 38 rng: &mut R, 39 region: &Region, 40 vertices_range: impl SampleRange<usize>, 41 ) -> Shape { 42 let number_of_anchors = rng.random_range(vertices_range); 43 let start = Point::random(rng, region); 44 let mut lines: Vec<LineSegment> = vec![]; 45 for _ in 0..number_of_anchors { 46 let next_anchor = Point::random(rng, region); 47 lines.push(Self::random_line_segment(rng, next_anchor)); 48 } 49 Shape::Polygon(start, lines) 50 } 51 52 pub fn random_line_segment<R: rand::Rng>( 53 rng: &mut R, 54 end: Point, 55 ) -> LineSegment { 56 match rng.random_range(1..=3) { 57 1 => LineSegment::Straight(end), 58 2 => LineSegment::InwardCurve(end), 59 3 => LineSegment::OutwardCurve(end), 60 _ => unreachable!(), 61 } 62 } 63 64 pub fn random( 65 rng: &mut impl Rng, 66 region: &Region, 67 line_width: f32, 68 polygon_vertices_range: impl SampleRange<usize>, 69 ) -> Shape { 70 let start = Point::random(rng, region); 71 Shape::random_starting_at( 72 rng, 73 start, 74 region, 75 line_width, 76 polygon_vertices_range, 77 ) 78 } 79 80 pub fn random_curve_within( 81 rng: &mut impl Rng, 82 region: &Region, 83 line_width: f32, 84 ) -> Shape { 85 let start = region.random_point(rng); 86 match rng.random_range(1..=3) { 87 1 => Shape::CurveInward( 88 start, 89 region.random_end(rng, start), 90 line_width, 91 ), 92 2 => Shape::CurveOutward( 93 start, 94 region.random_end(rng, start), 95 line_width, 96 ), 97 3 => Shape::Line( 98 Point::random(rng, region), 99 Point::random(rng, region), 100 line_width, 101 ), 102 _ => unreachable!(), 103 } 104 } 105} 106 107impl Object { 108 pub fn flickering(self, rng: &mut impl Rng, amplitude: f32) -> Self { 109 self.opacified(rng.random_range((1.0 - amplitude).max(0.0)..1.0)) 110 } 111 112 pub fn pick_random_tag<R: rand::Rng>( 113 &mut self, 114 rng: &mut R, 115 tags: &[&str], 116 ) -> String { 117 self.tag(tags.choose(rng).expect("Coudln't choose tag")) 118 } 119}