feat: added more interpolation options
added the following interpolation options: - cubic ease-in-out - cosine - exponential
This commit is contained in:
parent
1d75337471
commit
cdb14a76d6
1 changed files with 79 additions and 6 deletions
85
src/lib.rs
85
src/lib.rs
|
@ -34,6 +34,17 @@ pub struct Config {
|
|||
pub disable_timeout: u32,
|
||||
pub gamma_backend: GammaBackend,
|
||||
pub temp_backend: TempBackend,
|
||||
|
||||
pub interpolation_temp: Interpolation,
|
||||
pub interpolation_gamma: Interpolation,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
pub enum Interpolation {
|
||||
Linear,
|
||||
CubicEaseInOut,
|
||||
Cosine,
|
||||
Exponential,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
|
@ -70,6 +81,8 @@ impl Default for Config {
|
|||
notification_timeout: 5000,
|
||||
gamma_backend: GammaBackend::Hyprctl,
|
||||
temp_backend: TempBackend::Hyprctl,
|
||||
interpolation_temp: Interpolation::Linear,
|
||||
interpolation_gamma: Interpolation::Linear,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +96,7 @@ pub enum ConfigError {
|
|||
InvalidGamma(String),
|
||||
InvalidGammaBackend(String),
|
||||
InvalidTempBackend(String),
|
||||
InvalidInterpolation(String),
|
||||
DuplicateKey(String),
|
||||
}
|
||||
|
||||
|
@ -230,6 +244,20 @@ impl Config {
|
|||
return Err(ConfigError::InvalidTime(value.to_string()));
|
||||
}
|
||||
}
|
||||
"interpolation_temp" => match value.to_lowercase().as_str() {
|
||||
"linear" => config.interpolation_temp = Interpolation::Linear,
|
||||
"cubic" | "cubiceaseinout" => config.interpolation_temp = Interpolation::CubicEaseInOut,
|
||||
"cosine" => config.interpolation_temp = Interpolation::Cosine,
|
||||
"exponential" => config.interpolation_temp = Interpolation::Exponential,
|
||||
_ => return Err(ConfigError::InvalidInterpolation(value.to_string())),
|
||||
},
|
||||
"interpolation_gamma" => match value.to_lowercase().as_str() {
|
||||
"linear" => config.interpolation_gamma = Interpolation::Linear,
|
||||
"cubic" | "cubiceaseinout" => config.interpolation_gamma = Interpolation::CubicEaseInOut,
|
||||
"cosine" => config.interpolation_gamma = Interpolation::Cosine,
|
||||
"exponential" => config.interpolation_gamma = Interpolation::Exponential,
|
||||
_ => return Err(ConfigError::InvalidInterpolation(value.to_string())),
|
||||
},
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
|
@ -256,8 +284,8 @@ impl Config {
|
|||
}
|
||||
|
||||
/// Linearly interpolate between start and end by factor [0.0, 1.0]
|
||||
pub fn interpolate(start: u16, end: u16, factor: f64) -> u16 {
|
||||
trace!("interpolate({start}, {end}, {factor})");
|
||||
pub fn interpolate_linear(start: u16, end: u16, factor: f64) -> u16 {
|
||||
trace!("interpolate_linear({start}, {end}, {factor})");
|
||||
if end < start {
|
||||
(end as f64 + (start - end) as f64 * (1.0 - factor)).round() as u16
|
||||
} else {
|
||||
|
@ -265,6 +293,51 @@ pub fn interpolate(start: u16, end: u16, factor: f64) -> u16 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Cubic interpolation
|
||||
fn interpolate_cubic(start: u16, end: u16, factor: f64) -> u16 {
|
||||
trace!("interpolate_cubic({start}, {end}, {factor})");
|
||||
let factor = factor.clamp(0.0, 1.0);
|
||||
// Convert to f64 for arithmetic
|
||||
let start_f = start as f64;
|
||||
let end_f = end as f64;
|
||||
// Cubic ease-in-out: 3t^2 - 2t^3
|
||||
let t = factor;
|
||||
let smooth_t = (3.0 * t * t) - (2.0 * t * t * t);
|
||||
// Interpolate
|
||||
let result = start_f + smooth_t * (end_f - start_f);
|
||||
// Round and clamp to u16 bounds
|
||||
result.round().max(0.0).min(u16::MAX as f64) as u16
|
||||
}
|
||||
|
||||
/// Cosine interpolation
|
||||
fn interpolate_cosine(start: u16, end: u16, factor: f64) -> u16 {
|
||||
trace!("interpolate_cosine({start}, {end}, {factor})");
|
||||
let t = (1.0 - (factor.clamp(0.0, 1.0) * std::f64::consts::PI).cos()) / 2.0;
|
||||
interpolate_linear(start, end, t)
|
||||
}
|
||||
|
||||
fn interpolate_exponential(start: u16, end: u16, factor: f64) -> u16 {
|
||||
trace!("interpolate_exponential({start}, {end}, {factor})");
|
||||
let t = factor.clamp(0.0, 1.0);
|
||||
let t = if t < 0.5 {
|
||||
0.5 * (2.0 * t).powf(3.0)
|
||||
} else {
|
||||
0.5 * (1.0 - (2.0 * (1.0 - t)).powf(3.0)) + 0.5
|
||||
};
|
||||
interpolate_linear(start, end, t)
|
||||
}
|
||||
|
||||
/// Interpolation meta-function
|
||||
fn interpolate_value(start: u16, end: u16, factor: f64, interpolation: &Interpolation) -> u16 {
|
||||
trace!("interpolate_value({start}, {end}, {factor}, {interpolation:?})");
|
||||
match interpolation {
|
||||
Interpolation::Linear => interpolate_linear(start, end, factor),
|
||||
Interpolation::CubicEaseInOut => interpolate_cubic(start, end, factor),
|
||||
Interpolation::Cosine => interpolate_cosine(start, end, factor),
|
||||
Interpolation::Exponential => interpolate_exponential(start, end, factor),
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute current temperature and gamma based on provided time
|
||||
pub fn compute_settings(now: Time, config: &Config) -> (u16, u16) {
|
||||
trace!("compute_settings({now:?})");
|
||||
|
@ -278,8 +351,8 @@ pub fn compute_settings(now: Time, config: &Config) -> (u16, u16) {
|
|||
/ (config.sunset_end - config.sunset_start) as f64)
|
||||
.clamp(0.0, 1.0);
|
||||
(
|
||||
interpolate(config.temp_day, config.temp_night, factor),
|
||||
interpolate(config.gamma_day, config.gamma_night, factor),
|
||||
interpolate_value(config.temp_day, config.temp_night, factor, &config.interpolation_temp),
|
||||
interpolate_value(config.gamma_day, config.gamma_night, factor, &config.interpolation_gamma),
|
||||
)
|
||||
} else if (time_in_hours >= config.sunrise_start as f64)
|
||||
&& (time_in_hours <= config.sunrise_end as f64)
|
||||
|
@ -290,8 +363,8 @@ pub fn compute_settings(now: Time, config: &Config) -> (u16, u16) {
|
|||
/ (config.sunrise_end - config.sunrise_start) as f64)
|
||||
.clamp(0.0, 1.0);
|
||||
(
|
||||
interpolate(config.temp_day, config.temp_night, factor),
|
||||
interpolate(config.gamma_day, config.gamma_night, factor),
|
||||
interpolate_value(config.temp_day, config.temp_night, factor, &config.interpolation_temp),
|
||||
interpolate_value(config.gamma_day, config.gamma_night, factor, &config.interpolation_gamma),
|
||||
)
|
||||
} else if time_in_hours > config.sunset_end as f64
|
||||
|| time_in_hours < config.sunrise_start as f64
|
||||
|
|
Loading…
Reference in a new issue