All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
100 lines
2.6 KiB
Rust
100 lines
2.6 KiB
Rust
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(())
|
|
}
|