修正wacg自适应推断算法为双向修正策略,以避免指定条件无法满足时死循环的发生。
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user