1pub fn distance(x1: f32, y1: f32, x2: f32, y2: f32) -> f32 {
16 ((x2 - x1).powi(2) + (y2 - y1).powi(2)).sqrt()
17}
18
19pub fn clamp(value: f32, min: f32, max: f32) -> f32 {
29 value.max(min).min(max)
30}
31
32pub fn lerp(start: f32, end: f32, t: f32) -> f32 {
42 start + (end - start) * clamp(t, 0.0, 1.0)
43}
44
45pub fn rgb_to_float(value: u8) -> f32 {
53 value as f32 / 255.0
54}
55
56pub fn float_to_rgb(value: f32) -> u8 {
64 (clamp(value, 0.0, 1.0) * 255.0).round() as u8
65}
66
67pub fn point_in_rect(x: f32, y: f32, rect_x: f32, rect_y: f32, rect_width: f32, rect_height: f32) -> bool {
80 x >= rect_x && x <= rect_x + rect_width && y >= rect_y && y <= rect_y + rect_height
81}
82
83pub fn generate_id() -> String {
88 use std::time::{SystemTime, UNIX_EPOCH};
89 let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos();
90 format!("{:x}", timestamp)
91}
92
93pub fn format_error(error: &dyn std::error::Error) -> String {
101 let mut message = error.to_string();
102 let mut current_error = error.source();
103 while let Some(cause) = current_error {
104 message.push_str(&format!("\nCaused by: {}", cause));
105 current_error = cause.source();
106 }
107 message
108}