use geo::algorithm::intersects::Intersects; use geo::algorithm::rotate::Rotate; use geo::prelude::Translate; use geo::rotate::RotatePoint; use geo::{Coordinate, MultiPolygon, Point, Polygon}; use geo::{LineString}; use geo_clipper::Clipper; use polygon_art::MultiPolygonExt; use polygon_art::{load_multipolgon_from_svg, Context}; use rand::prelude::StdRng; use rand::Rng; fn main() { let mut context = Context::create(); let mut rng = context.gen_rng(); let ship_width = 100.; let center_point = MultiPolygon(vec![create_asteroid(&mut rng, 20, 2)]) .scale_to_width(2.5 * ship_width) .translate(context.width / 2., context.height / 2.); // create asteroid let mut asteroids: Vec> = Vec::new(); for _ in 0..40 { let without_orbit = rng.gen_range(40..140) as f64; let with_orbit = without_orbit * 1.32; let x = rng.gen_range(0..(context.width as i32)) as f64; let y = rng.gen_range(0..(context.height as i32)) as f64; let asteroid = MultiPolygon(vec![create_asteroid(&mut rng, 20, 15)]) .scale_to_width(with_orbit) .translate(x, y); if !center_point.intersects(&asteroid) && asteroids .iter() .find(|&m| *&m.intersects(&asteroid)) .is_none() { asteroids.push(asteroid.scale_to_width(without_orbit)); } if asteroids.len() > 23 { break; } } // load ships let rotation = rng.gen_range(0..360); let ship = load_multipolgon_from_svg("pool/asteroids/ship3.svg") .unwrap() .scale_to_width(ship_width) .translate_center() .rotate(rotation as f64); context.translate_center(); context.draw_multipolygon(&ship); context.restore(); // drawing and clipping let frame_space = 10.; let window = context.frame(frame_space, frame_space, frame_space, frame_space); context.draw_polygon(&window); for asteroid in asteroids.iter() { context.draw_multipolygon(&asteroid.intersection(&window, 100.)); } context.render(); } fn create_asteroid(rng: &mut StdRng, subdivisions: i32, radius_randomization: i32) -> Polygon { let mut asteroid_points: Vec> = Vec::new(); for _ in 0..subdivisions { let change = rng.gen_range(0..(radius_randomization * 2)); asteroid_points.push(Point(Coordinate { x: 0.0, y: 100.0 + (change - radius_randomization) as f64, })); for point in asteroid_points.iter_mut() { let (x, y) = point .rotate_around_point( 360. / subdivisions as f64, Point(Coordinate { x: 0., y: 0. }), ) .x_y(); point.set_x(x); point.set_y(y); } } Polygon::new( LineString(asteroid_points.iter().map(|point| point.0).collect()), Vec::new(), ) }