55 lines
1.7 KiB
Rust
55 lines
1.7 KiB
Rust
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
|
|
}
|