From 079911b947b412f5ece3c1542eb9c7168952e779 Mon Sep 17 00:00:00 2001 From: "0m.ax" Date: Sat, 19 Jul 2025 03:00:35 +0200 Subject: [PATCH] color --- src/color.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 10 ++++++-- 2 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 src/color.rs diff --git a/src/color.rs b/src/color.rs new file mode 100644 index 0000000..2b3b9dd --- /dev/null +++ b/src/color.rs @@ -0,0 +1,69 @@ +use std::fmt; + +/// Represents a color in the RGB (Red, Green, Blue) model. +/// Values range from 0 to 255. +pub struct Rgb { + pub r: u8, + pub g: u8, + pub b: u8, +} + +/// Represents a color in the HSV (Hue, Saturation, Value) model. +/// - `h` (hue): 0-359 degrees +/// - `s` (saturation): 0.0-1.0 +/// - `v` (value/brightness): 0.0-1.0 +pub struct Hsv { + pub h: u16, + pub s: f32, + pub v: f32, +} + +// Implement the `Debug` trait for Rgb to allow pretty-printing. +impl fmt::Debug for Rgb { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Rgb({}, {}, {})", self.r, self.g, self.b) + } +} + + +/// Provides the conversion logic from HSV to RGB. +/// This uses the standard mathematical formula for the conversion. +impl From for Rgb { + fn from(hsv: Hsv) -> Self { + // Ensure saturation and value are within the valid range [0.0, 1.0] + let s = hsv.s.clamp(0.0, 1.0); + let v = hsv.v.clamp(0.0, 1.0); + + // When saturation is 0, the color is a shade of gray. + if s == 0.0 { + let val = (v * 255.0) as u8; + return Rgb { r: val, g: val, b: val }; + } + + // The hue is treated as a sector on a color wheel. + let h = hsv.h as f32 / 60.0; // Sector 0-5 + let i = h.floor() as i32; + let f = h - i as f32; // Fractional part of h + + let p = v * (1.0 - s); + let q = v * (1.0 - f * s); + let t = v * (1.0 - (1.0 - f) * s); + + // Determine the RGB values based on the hue sector. + let (r, g, b) = match i { + 0 => (v, t, p), + 1 => (q, v, p), + 2 => (p, v, t), + 3 => (p, q, v), + 4 => (t, p, v), + _ => (v, p, q), // Default case for sector 5 + }; + + // Convert the float RGB values (0.0-1.0) to u8 values (0-255). + Rgb { + r: (r * 255.0).round() as u8, + g: (g * 255.0).round() as u8, + b: (b * 255.0).round() as u8, + } + } +} diff --git a/src/main.rs b/src/main.rs index 5fa9f4b..0cbaa98 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use std::fs::File; use std::io::BufReader; use std::net::{ToSocketAddrs, UdpSocket}; use std::time::Duration; - +mod color; // Constants from the C code const QUEUE_LEN: usize = 1000; const MSG_PAYLOAD_SIZE: usize = 7 * 211; @@ -189,7 +189,13 @@ impl Drawable for Circle { /// Helper method to draw the 8 symmetric points for a given (x, y) offset. fn draw_and_move(&mut self, display: &mut Display) { - self.draw_circle(display,self.x,self.y,self.radius,255,255,255); + let hsv_color = color::Hsv { + h: 360, + s: 1.0, + v: 1.0, + }; + let rgb: color::Rgb = hsv_color.into(); + self.draw_circle(display,self.x,self.y,self.radius,rgb.r,rgb.g,rgb.b); self.radius = self.radius + 1; if self.radius > 1080/2 { self.radius = 1;