diff --git a/src/main.rs b/src/main.rs index 9ce4bf0..ce45b4f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ use std::{ collections::{HashMap, HashSet}, env, + f64::consts::SQRT_2, }; use hsl::HSL; @@ -26,20 +27,20 @@ fn main() { // get length of path, find covered // jk we can't precompute covered - let mut covered: HashSet<(u32, u32)> = HashSet::new(); - let mut front = HashSet::new(); - front.insert((start_x, start_y)); - let mut step: u32 = 0; + let mut covered: HashMap<(u32, u32), f64> = HashMap::new(); + let mut front = HashMap::new(); + front.insert((start_x, start_y), 0.01); loop { - let mut new_front = HashSet::new(); - for (x, y) in &front { - for (x, y) in adjacent(*x, *y) { + let mut new_front = HashMap::new(); + for ((ox, oy), dist) in &front { + for (x, y) in adjacent(*ox, *oy) { if img.in_bounds(x, y) && !is_dark(img.get_pixel(x, y).to_rgb()) - && !covered.contains(&(x, y)) + && !covered.contains_key(&(x, y)) { - new_front.insert((x, y)); + let moved = if x == *ox || y == *oy { 1.0 } else { SQRT_2 }; + new_front.insert((x, y), dist + moved); } } } @@ -50,31 +51,37 @@ fn main() { covered.extend(new_front.iter()); front = new_front; - step += 1; } // color :D - let change_per_step = 360. / f64::from(step).max(1.); + let max_dist = front + .values() + .max_by_key(|n| n.floor() as u64) + .unwrap_or(&1.); + let change_per_dist = 360. / max_dist; let mut covered: HashSet<(u32, u32)> = HashSet::new(); let mut front = HashMap::new(); - front.insert((start_x, start_y), HSL::from_rgb(&[255, 0, 0])); + front.insert((start_x, start_y), (HSL::from_rgb(&[255, 0, 0]), 0.01)); loop { let mut new_front = HashMap::new(); - for ((x, y), hsl) in &front { - for (x, y) in adjacent(*x, *y) { + for ((ox, oy), (hsl, dist)) in &front { + for (x, y) in adjacent(*ox, *oy) { if img.in_bounds(x, y) && !is_dark(img.get_pixel(x, y).to_rgb()) && !covered.contains(&(x, y)) { let mut color = *hsl; - color.h += change_per_step; + color.h = change_per_dist * dist; if color.h >= 360. { color.h = 0.; } - let (r, g, b) = color.to_rgb(); - new_front.insert((x, y), color); + + let moved = if x == *ox || y == *oy { 1.0 } else { SQRT_2 }; + + new_front.insert((x, y), (color, dist + moved)); + img.put_pixel(x, y, Rgba([r, g, b, 255])); } }