diff --git a/src/main.rs b/src/main.rs index e5ec128..c7be567 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,11 @@ extern crate minifb; use minifb::{Key, WindowOptions, Window}; +use std::f64; +use std::cmp; -const WIDTH: usize = 360; -const HEIGHT: usize = 100; +const WIDTH: usize = 640; +const HEIGHT: usize = 480; fn hsl_to_rgb(h: i32, s: f64, l: f64) -> u32 { //println!("h: {}, s: {}, l: {}", h, s, l); @@ -27,6 +29,18 @@ fn hsl_to_rgb(h: i32, s: f64, l: f64) -> u32 { b.round() as u32 + ((g.round() as u32) << 8) + ((r.round() as u32) << 16) } +fn distance_from_center(x: i32, y: i32, center_x: i32, center_y: i32) -> f64 { + return (((x - center_x) * (x - center_x) + (y - center_y) * (y - center_y)) as f64).sqrt() +} + +fn angle_from_center(x: i32, y: i32, center_x: i32, center_y: i32) -> f64 { + let mut angle = ((y - center_y) as f64).atan2((x - center_x) as f64) * 180.0 / f64::consts::PI; + if angle < 0.0 { + angle = angle + 360.0; + } + return angle +} + fn main() { let mut buffer: Vec = vec![0; WIDTH * HEIGHT]; @@ -37,17 +51,29 @@ fn main() { panic!("{}", e); }); + let mut time: i32 = 0; while window.is_open() && !window.is_key_down(Key::Escape) { let s: f64 = 1.0; + let (center_x, center_y) = ((WIDTH / 2) as i32, (HEIGHT / 2) as i32); + let (radius_min, radius_max) = (0.35 * cmp::min(WIDTH, HEIGHT) as f64, + 0.4 * cmp::min(WIDTH, HEIGHT) as f64); - for h in 0..WIDTH { - for l in 0..HEIGHT { - buffer[h + l * WIDTH] = hsl_to_rgb(h as i32, s, l as f64 / 100.0); + for y in 0..HEIGHT { + for x in 0..WIDTH { + let distance = distance_from_center(x as i32, y as i32, center_x, center_y); + let angle = (angle_from_center(x as i32, y as i32, center_x, center_y) as i32 + time) % 360; + + if distance > radius_min && distance < radius_max { + buffer[x + y * WIDTH] = hsl_to_rgb(angle, s, 0.5); + } else { + buffer[x + y * WIDTH] = 0; + } } } // We unwrap here as we want this code to exit if it fails. Real applications may want to handle this in a different way window.update_with_buffer(&buffer).unwrap(); + time += 10; } } @@ -68,6 +94,19 @@ mod tests { assert_eq!(computed, expected, "HSL to RGB conversion failed: {}. Got {:06X}, expected {:06X}", name, computed, expected); } + #[test] + fn test_angle_from_center() { + assert_eq!(angle_from_center(2, 2, 1, 1), 45.0); + assert_eq!(angle_from_center(0, 2, 1, 1), 135.0); + assert_eq!(angle_from_center(0, 0, 1, 1), 225.0); + assert_eq!(angle_from_center(2, 0, 1, 1), 315.0); + } + + #[test] + fn test_distance_from_center() { + assert_eq!(distance_from_center(6, 7, 3, 3), 5.0); + } + // Test cases from https://www.rapidtables.com/convert/color/hsl-to-rgb.html #[test] fn test_hsl_to_rgb_black() {