pub fn distance(x1: f32, y1: f32, x2: f32, y2: f32) -> f32 {
((x2 - x1).powi(2) + (y2 - y1).powi(2)).sqrt()
}
pub fn clamp(value: f32, min: f32, max: f32) -> f32 {
value.max(min).min(max)
}
pub fn lerp(start: f32, end: f32, t: f32) -> f32 {
start + (end - start) * clamp(t, 0.0, 1.0)
}
pub fn rgb_to_float(value: u8) -> f32 {
value as f32 / 255.0
}
pub fn float_to_rgb(value: f32) -> u8 {
(clamp(value, 0.0, 1.0) * 255.0).round() as u8
}
pub fn point_in_rect(x: f32, y: f32, rect_x: f32, rect_y: f32, rect_width: f32, rect_height: f32) -> bool {
x >= rect_x && x <= rect_x + rect_width && y >= rect_y && y <= rect_y + rect_height
}
pub fn generate_id() -> String {
use std::time::{SystemTime, UNIX_EPOCH};
let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos();
format!("{:x}", timestamp)
}
pub fn format_error(error: &dyn std::error::Error) -> String {
let mut message = error.to_string();
let mut current_error = error.source();
while let Some(cause) = current_error {
message.push_str(&format!("\nCaused by: {}", cause));
current_error = cause.source();
}
message
}