use geo::algorithm::rotate::{Rotate, RotatePoint}; use geo::algorithm::translate::Translate; use geo::{polygon, Coordinate, MultiPolygon, Point}; use geo_clipper::Clipper; use polygon_art::{Context, MergeExt, TranslateExt}; use rand::prelude::StdRng; use rand::Rng; fn main() { let mut context = Context::create(); context.translate_center(); let min = f64::min(context.width, context.height); let number_of_rings = (min / 150.) as i32; let mut radius = min / 2. - 5.; for _ in 0..number_of_rings { let ring_size = context.gen_rng().gen_range(10..(radius as i32 / 5)) as f64; radius = radius - ring_size; if radius < 10. { break; } let polygons = generate_ring(&mut context.gen_rng(), radius, ring_size); radius = radius - ring_size; context.draw_multipolygon(&polygons); } context.render(); } fn generate_ring(rng: &mut StdRng, radius: f64, ring_size: f64) -> MultiPolygon<f64> { let main = polygon![ (x: 0.0, y:0.0), (x: ring_size , y:0.0), (x: ring_size , y:ring_size ), (x: 0.0, y:ring_size ), ] .translate_center() .rotate(30.) .translate(0., radius); let center_point = Point(Coordinate { x: 0., y: 0. }); let parts = rng.gen_range(20..120); let rotation = 360. / parts as f64; let direction = if rng.gen_bool(0.5) { -1. } else { 1. }; let fragment = main.difference( &main.rotate_around_point(direction * rotation, center_point), 100., ); let mut polygons: MultiPolygon<f64> = MultiPolygon(Vec::new()); for index in 0..parts { polygons.merge(&fragment.rotate_around_point(rotation * index as f64, center_point)); } polygons }