From 13fd31f6327eeb5a0ccccb8bec5c3f213903383b Mon Sep 17 00:00:00 2001 From: lisk77 Date: Sun, 30 Mar 2025 14:54:28 +0200 Subject: [PATCH] feat: added a `from_vec` function to every color that it can be constructed with a `Vec4` to easily interpolate colors --- crates/comet_colors/src/hsla.rs | 4 + crates/comet_colors/src/hsva.rs | 4 + crates/comet_colors/src/hwba.rs | 4 + crates/comet_colors/src/laba.rs | 4 + crates/comet_colors/src/lcha.rs | 4 + crates/comet_colors/src/lib.rs | 1 + crates/comet_colors/src/linear_rgba.rs | 4 + crates/comet_colors/src/oklaba.rs | 4 + crates/comet_colors/src/oklcha.rs | 4 + crates/comet_colors/src/rgba.rs | 8 + crates/comet_colors/src/xyza.rs | 4 + crates/comet_math/src/utilities.rs | 208 ------------------------- src/lib.rs | 1 + 13 files changed, 46 insertions(+), 208 deletions(-) delete mode 100644 crates/comet_math/src/utilities.rs diff --git a/crates/comet_colors/src/hsla.rs b/crates/comet_colors/src/hsla.rs index 21f7d60..6a7601c 100644 --- a/crates/comet_colors/src/hsla.rs +++ b/crates/comet_colors/src/hsla.rs @@ -109,4 +109,8 @@ impl Color for Hsla { fn to_vec(&self) -> Vec4 { Vec4::new(self.hue, self.saturation, self.lightness, self.alpha) } + + fn from_vec(color: Vec4) -> Self { + Self::new(color.x(), color.y(), color.z(), color.w()) + } } \ No newline at end of file diff --git a/crates/comet_colors/src/hsva.rs b/crates/comet_colors/src/hsva.rs index f5c6789..2ce37ca 100644 --- a/crates/comet_colors/src/hsva.rs +++ b/crates/comet_colors/src/hsva.rs @@ -107,4 +107,8 @@ impl Color for Hsva { fn to_vec(&self) -> Vec4 { Vec4::new(self.hue, self.saturation, self.value, self.alpha) } + + fn from_vec(color: Vec4) -> Self { + Self::new(color.x(), color.y(), color.z(), color.w()) + } } \ No newline at end of file diff --git a/crates/comet_colors/src/hwba.rs b/crates/comet_colors/src/hwba.rs index cc0992b..deef7da 100644 --- a/crates/comet_colors/src/hwba.rs +++ b/crates/comet_colors/src/hwba.rs @@ -170,4 +170,8 @@ impl Color for Hwba { fn to_vec(&self) -> Vec4 { Vec4::new(self.hue, self.whiteness, self.blackness, self.alpha) } + + fn from_vec(color: Vec4) -> Self { + Self::new(color.x(), color.y(), color.z(), color.w()) + } } \ No newline at end of file diff --git a/crates/comet_colors/src/laba.rs b/crates/comet_colors/src/laba.rs index 0cfe83f..32fa89d 100644 --- a/crates/comet_colors/src/laba.rs +++ b/crates/comet_colors/src/laba.rs @@ -151,4 +151,8 @@ impl Color for Laba { fn to_vec(&self) -> Vec4 { Vec4::new(self.lightness, self.a, self.b, self.alpha) } + + fn from_vec(color: Vec4) -> Self { + Self::new(color.x(), color.y(), color.z(), color.w()) + } } \ No newline at end of file diff --git a/crates/comet_colors/src/lcha.rs b/crates/comet_colors/src/lcha.rs index d9e67ad..5f3ca8c 100644 --- a/crates/comet_colors/src/lcha.rs +++ b/crates/comet_colors/src/lcha.rs @@ -101,4 +101,8 @@ impl Color for Lcha { fn to_vec(&self) -> Vec4 { Vec4::new(self.lightness, self.chroma, self.hue, self.alpha) } + + fn from_vec(color: Vec4) -> Self { + Self::new(color.x(), color.y(), color.z(), color.w()) + } } \ No newline at end of file diff --git a/crates/comet_colors/src/lib.rs b/crates/comet_colors/src/lib.rs index aedca2a..0949fe7 100644 --- a/crates/comet_colors/src/lib.rs +++ b/crates/comet_colors/src/lib.rs @@ -25,4 +25,5 @@ mod oklcha; pub trait Color: Copy { fn to_wgpu(&self) -> wgpu::Color; fn to_vec(&self) -> Vec4; + fn from_vec(color: Vec4) -> Self; } \ No newline at end of file diff --git a/crates/comet_colors/src/linear_rgba.rs b/crates/comet_colors/src/linear_rgba.rs index 35ab5a5..554cc61 100644 --- a/crates/comet_colors/src/linear_rgba.rs +++ b/crates/comet_colors/src/linear_rgba.rs @@ -139,4 +139,8 @@ impl Color for LinearRgba { fn to_vec(&self) -> Vec4 { Vec4::new(self.red, self.green, self.blue, self.alpha) } + + fn from_vec(color: Vec4) -> Self { + Self::new(color.x(), color.y(), color.z(), color.w()) + } } \ No newline at end of file diff --git a/crates/comet_colors/src/oklaba.rs b/crates/comet_colors/src/oklaba.rs index 3c114bf..fe0f0f5 100644 --- a/crates/comet_colors/src/oklaba.rs +++ b/crates/comet_colors/src/oklaba.rs @@ -121,4 +121,8 @@ impl Color for Oklaba { fn to_vec(&self) -> Vec4 { Vec4::new(self.lightness, self.a, self.b, self.alpha) } + + fn from_vec(color: Vec4) -> Self { + Self::new(color.x(), color.y(), color.z(), color.w()) + } } \ No newline at end of file diff --git a/crates/comet_colors/src/oklcha.rs b/crates/comet_colors/src/oklcha.rs index ec0d856..7d9d8cc 100644 --- a/crates/comet_colors/src/oklcha.rs +++ b/crates/comet_colors/src/oklcha.rs @@ -100,4 +100,8 @@ impl Color for Oklcha { fn to_vec(&self) -> Vec4 { Vec4::new(self.lightness, self.chroma, self.hue, self.alpha) } + + fn from_vec(color: Vec4) -> Self { + Self::new(color.x(), color.y(), color.z(), color.w()) + } } \ No newline at end of file diff --git a/crates/comet_colors/src/rgba.rs b/crates/comet_colors/src/rgba.rs index 20aef06..c7ee1ac 100644 --- a/crates/comet_colors/src/rgba.rs +++ b/crates/comet_colors/src/rgba.rs @@ -352,6 +352,10 @@ impl Color for sRgba { fn to_vec(&self) -> Vec4 { Vec4::new(self.red, self.green, self.blue, self.alpha) } + + fn from_vec(color: Vec4) -> Self { + Self::new(color.x(), color.y(), color.z(), color.w()) + } } impl Color for sRgba { @@ -367,4 +371,8 @@ impl Color for sRgba { self.alpha as f32 ) } + + fn from_vec(color: Vec4) -> Self { + Self::new(color.x() as u8, color.y() as u8, color.z() as u8, color.w() as u8) + } } \ No newline at end of file diff --git a/crates/comet_colors/src/xyza.rs b/crates/comet_colors/src/xyza.rs index a665d2a..9d41ac0 100644 --- a/crates/comet_colors/src/xyza.rs +++ b/crates/comet_colors/src/xyza.rs @@ -117,4 +117,8 @@ impl Color for Xyza { fn to_vec(&self) -> Vec4 { Vec4::new(self.x, self.y, self.z, self.alpha) } + + fn from_vec(color: Vec4) -> Self { + Self::new(color.x(), color.y(), color.z(), color.w()) + } } \ No newline at end of file diff --git a/crates/comet_math/src/utilities.rs b/crates/comet_math/src/utilities.rs deleted file mode 100644 index e21ab10..0000000 --- a/crates/comet_math/src/utilities.rs +++ /dev/null @@ -1,208 +0,0 @@ -use crate::point::{Point2, Point3}; -use crate::vector::{Vec2, Vec3, Vec4, InnerSpace}; - -// ################################################## -// # CONSTANTS # -// ################################################## - -static FAC: [i64; 21] = [ - 1,1,2,6,24,120,720,5040,40320,362880,3628800, - 39916800,479001600,6227020800,87178291200,1307674368000, - 20922789888000,355687428096000,6402373705728000, - 121645100408832000,2432902008176640000 -]; - -static INV_FAC: [f32; 6] = [ - 1.0,1.0,0.5,0.1666666666666666667,0.04166666666666666667,0.00833333333333333334 -]; - -pub static PI: f32 = std::f32::consts::PI; - -// ################################################## -// # GENERAL PURPOSE # -// ################################################## - -pub fn fac(n: i64) -> i64 { - match n { - _ if n <= 21 => { FAC[n as usize] } - _ => n * fac(n-1) - } -} - -pub fn sqrt(x: f32) -> f32 { - x.sqrt() -} - -pub fn ln(x: f32) -> f32 { - x.ln() -} - -pub fn log(x: f32) -> f32 { - ln(x)/ std::f32::consts::LN_10 -} - -pub fn log2(x: f32) -> f32 { - ln(x)/ std::f32::consts::LN_2 -} - -pub fn sin(x: f32) -> f32 { - x.sin() -} - -pub fn asin(x: f32) -> f32 { - x.asin() -} - -pub fn cos(x: f32) -> f32 { - x.cos() -} - -pub fn acos(x: f32) -> f32 { - x.acos() -} - -pub fn tan(x: f32) -> f32 { - x.tan() -} - -pub fn atan(x: f32) -> f32 { - x.atan() -} - -pub fn atan2(p: Point2) -> f32 { - p.y().atan2(p.x()) -} - -pub fn sinh(x: f32) -> f32 { - x.sinh() -} - -pub fn cosh(x: f32) -> f32 { - x.cosh() -} - -pub fn tanh(x: f32) -> f32 { - x.tanh() -} - -pub fn clamp(start: f32, end: f32, value: f32) -> f32 { - match value { - _ if value > end => end, - _ if start > value => start, - _ => value - } -} - -// Getting the derivative of a function at a point with a given h vaLue for -pub fn point_derivative(func: fn(f32) -> f32, x: f32, h: f32) -> f32 { - (func(x+h) - func(x-h))/(2.0 * h) -} - -// ################################################## -// # INTERPOLATION # -// ################################################## - -/// Linear interpolation between the values `a` and `b` with the parameter `t`, while `t` is in the range [0,1]. -pub fn lerp(a: f32, b: f32, t: f32) -> f32 { - (1.0 - t) * a + t * b -} - -/// The inverse operation of linear interpolation. Given the values `a` and `b` and the result `value`, this function returns the parameter `t`. -pub fn inv_lerp(a: f32, b:f32, value: f32) -> f32 { - (value - a) / (b - a) -} - -/// Two-dimensional linear interpolation between the values `a` and `b` with the parameter `t`, while `t` is in the range [0,1]. -pub fn lerp2(a: Vec2, b: Vec2, t: f32) -> Vec2 { - a * (1.0 - t) + b * t -} - -/// The inverse operation of the two-dimensional linear interpolation. Given the values `a` and `b` and the result `value`, this function returns the parameter `t`. -pub fn inv_lerp2(a: Vec2, b: Vec2, value: Vec2) -> Option { - let tx = (value.x() - a.x()) / (b.x() - a.x()); - let ty = (value.y() - a.y()) / (b.y() - a.y()); - - if tx == ty { - return Some(tx); - } - None -} - -/// Three-dimensional linear interpolation between the values `a` and `b` with the parameter `t`, while `t` is in the range [0,1]. -pub fn lerp3(a: Vec3, b: Vec3, t: f32) -> Vec3 { - a * (1.0 - t) + b * t -} - -/// The inverse operation of the three-dimensional linear interpolation. Given the values `a` and `b` and the result `value`, this function returns the parameter `t`. -pub fn inv_lerp3(a: Vec3, b: Vec3, value: Vec3) -> Option { - let tx = (value.x() - a.x())/(b.x() - a.x()); - let ty = (value.y() - a.y())/(b.y() - a.y()); - let tz = (value.z() - a.z())/(b.z() - a.z()); - - if (tx == ty) && (ty == tz) { - return Some(tx); - } - None -} - -/// Four-dimensional linear interpolation between the values `a` and `b` with the parameter `t`, while `t` is in the range [0,1]. -pub fn lerp4(a: Vec4, b: Vec4, t: f32) -> Vec4 { - a * (1.0 - t) + b * t -} - -/// The inverse operation of the four-dimensional linear interpolation. Given the values `a` and `b` and the result `value`, this function returns the parameter `t`. -pub fn inv_lerp4(a: Vec4, b: Vec4, value: Vec4) -> Option { - let tx = (value.x() - a.x())/(b.x() - a.x()); - let ty = (value.y() - a.y())/(b.y() - a.y()); - let tz = (value.z() - a.z())/(b.z() - a.z()); - let tw = (value.w() - a.w())/(b.w() - a.w()); - - if (tx == ty) && (ty == tz) && (tz == tw) { - return Some(tx); - } - None -} - -/// Cubic interpolation with the polynomial 3t² - 2t³ -fn cubic_interpolation(a: f32, b: f32, t: f32) -> f32 { - let g = (3.0 - t * 2.0) * t * t; - (b-a) * g + a -} - -// ################################################## -// # BEZIER CURVES # -// ################################################## - -/// Cubic Bézier Curve in R² -pub fn bezier2(p0: Point2, p1: Point2, p2: Point2, p3: Point2, t: f32) -> Point2 { - let t_squared = t * t; - let t_cubed = t_squared * t; - let v_p0 = Vec2::from_point(p0); - let v_p1 = Vec2::from_point(p1); - let v_p2 = Vec2::from_point(p2); - let v_p3 = Vec2::from_point(p3); - - Point2::from_vec(v_p0 * (-t_cubed + 3.0 * t_squared - 3.0 * t + 1.0 ) + - v_p1 * (3.0 * t_cubed - 6.0 * t_squared + 3.0 * t ) + - v_p2 * (-3.0 * t_cubed + 3.0 * t_squared ) + - v_p3 * t_cubed) -} - -/// Cubic Bézier Curve in R³ -pub fn bezier3(p0: Point3, p1: Point3, p2: Point3, p3: Point3, t: f32) -> Point3 { - let t_squared = t * t; - let t_cubed = t_squared * t; - let v_p0 = Vec3::from_point(p0); - let v_p1 = Vec3::from_point(p1); - let v_p2 = Vec3::from_point(p2); - let v_p3 = Vec3::from_point(p3); - - Point3::from_vec(v_p0 * (-t_cubed + 3.0 * t_squared - 3.0 * t + 1.0 ) + - v_p1 * (3.0 * t_cubed - 6.0 * t_squared + 3.0 * t ) + - v_p2 * (-3.0 * t_cubed + 3.0 * t_squared ) + - v_p3 * t_cubed) -} - -// ################################################## -// # SPLINES # -// ################################################## diff --git a/src/lib.rs b/src/lib.rs index df7274f..c2740ce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,7 @@ pub mod prelude { pub use winit_input_helper::WinitInputHelper as InputManager; pub use comet_log::*; pub use comet_colors::*; + pub use comet_colors::Color; pub use comet_ecs::*; pub use comet_math::*; } \ No newline at end of file