use cairo::Context; use rand::{rngs::ThreadRng, Rng}; use crate::color::Color; static COLORS: [(&str, &str); 3] = [ ("#F4A263", "#E87052"), ("#E0DA48", "#969A1D"), ("#309E8F", "#2F3F52"), ]; fn calculate_polygon_corners( center: (f64, f64), num_sides: i32, radius: f64, rotation_angle_degrees: f64, ) -> Vec<(f64, f64)> { // no idea how this code works, it was written by ChatGPT let mut corners = Vec::new(); let rotation_angle = rotation_angle_degrees.to_radians(); let angle = std::f64::consts::PI / (num_sides as f64); for i in 0..num_sides { let vertex_angle = angle * (2.0 * i as f64 + 1.0 - num_sides as f64) + rotation_angle; let x = center.0 + radius * vertex_angle.sin(); let y = center.1 + radius * vertex_angle.cos(); corners.push((x, y)); } corners } fn set_color(color: Color, context: &Context) { context.set_source_rgb( color.r as f64 / 255.0, color.g as f64 / 255.0, color.b as f64 / 255.0, ); } fn generate_colors(rng: &mut ThreadRng) -> (Color, Color) { let color_num = rng.gen_range(0..COLORS.len()); let (c1, c2) = COLORS[color_num]; (Color::from_hex(c1), Color::from_hex(c2)) } pub fn draw_segmented_polygon( center: (f64, f64), side_length: f64, num_sides: i32, context: &Context, ) -> Result<(), cairo::Error> { let mut rng = rand::thread_rng(); let (c1, c2) = generate_colors(&mut rng); set_color(c1, context); context.new_path(); let corners = calculate_polygon_corners(center, num_sides, side_length, 30.0); let corner1: u8 = rng.gen_range(0..6); let corner2: u8 = (corner1 + rng.gen_range(2..5)) % 6; let from_corner = std::cmp::min(corner1, corner2); let to_corner = std::cmp::max(corner1, corner2); // draw one side for i in from_corner..(to_corner + 1) { let (x, y) = corners[i as usize]; context.line_to(x, y); } context.close_path(); context.fill()?; set_color(c2, context); context.new_path(); // draw other side for i in to_corner..(from_corner + 1 + 6) { let (x, y) = corners[(i % 6) as usize]; context.line_to(x, y); } context.close_path(); context.fill()?; Ok(()) } pub fn draw_polygon_of_segmented_polygons( center: (f64, f64), radius: f64, inner_radius: f64, num_sides: i32, context: &Context, ) -> Result<(), cairo::Error> { let corners = calculate_polygon_corners(center, num_sides, radius, 0.0); for corner in corners { draw_segmented_polygon(corner, inner_radius, num_sides, &context)?; } Ok(()) }