修正wacg自适应推断算法为双向修正策略,以避免指定条件无法满足时死循环的发生。

This commit is contained in:
徐涛
2025-02-06 10:45:47 +08:00
parent 59519e1408
commit e3642cad97
5 changed files with 113 additions and 104 deletions

View File

@@ -25,28 +25,37 @@ pub struct ColorSet {
fn fit_to_wacg(reference: &Oklch, neutral_swatch: &NeutralSwatch, ratio: f32) -> Oklch {
let reference_luma = map_oklch_to_luma(reference);
let mut new_target = neutral_swatch.get(reference.l);
let quick_factor: f32 = if reference.l <= 0.5 { 0.05 } else { -0.05 };
let fine_factor: f32 = if reference.l <= 0.5 { 0.01 } else { -0.01 };
let factor: f32 = if reference.l <= 0.5 { 0.01 } else { -0.01 };
let match_wacg = |original: &Oklch<f32>, reference: &Luma| {
let luma = map_oklch_to_luma(original);
luma.relative_contrast(*reference)
};
while match_wacg(&new_target, &reference_luma) < ratio {
new_target.l = new_target.l * (1.0 + quick_factor);
if new_target.l > 1.0 {
new_target.l = 1.0;
let mut last_contrast_ratio = 0.0;
let mut repeat_count = 0;
let mut target_ratio = ratio;
loop {
let contrast_ratio = match_wacg(&new_target, &reference_luma);
if contrast_ratio >= target_ratio {
break;
}
}
while match_wacg(&new_target, &reference_luma) < ratio {
new_target.l = new_target.l * (1.0 + fine_factor);
if new_target.l > 1.0 {
new_target.l = 1.0;
break;
if (contrast_ratio - last_contrast_ratio).abs() / last_contrast_ratio < 0.001 {
repeat_count += 1;
if repeat_count > 20 {
target_ratio *= 1.0 - 0.01;
repeat_count = 0;
}
} else {
repeat_count = 0;
}
last_contrast_ratio = contrast_ratio;
new_target = Oklch {
l: new_target.l * (1.0 + factor),
..new_target
};
}
new_target
}