fix(design): 中性色相常量改容差断言 + 取色接线注释指向真正的守护测试(复审 r1 p2)
- `palettes.rs::neutral_hue_is_the_default_seed_hue`:`to_bits()` 位相等 → 1e-9° 容差。 色相来自 `atan2(a).to_degrees()`,`NEUTRAL_HUE_DEG` 的字面值是在 Windows(UCRT) 上取的, CI 的 ubuntu(glibc) 理论上可差 1 ulp 就让位相等在另一个 OS 上红;而这条要抓的是「换了 `DEFAULT_SEED` 却没复核常量」(偏几十度),1e-9° 足够且不受平台末位差影响。 `tests/card_neutral.rs::sky_card_is_bit_identical_to_the_product_baseline` 是**同平台内** 两个算出来的值互比,继续用位相等(p1 硬约束的钉子,不动)。 常量文档同步说明「为什么不用 `to_bits`」。 - `resolve/mod.rs` 取色分支的注释:原来只写「`tests/card_neutral.rs` 有反证」,而那条用例 测的是 `Seed::scheme` 生成器层、覆盖不到这里(复审 r1 p1-1 的病根)。改成点名 `resolved_image_scheme_keeps_tinting_from_the_seed`——走的就是本函数的公开入口。 `palettes.rs` 仍是 400 行(本轮改 doc 同时压缩了相邻说明,没突破上限)。
This commit is contained in:
1 parent
b748986aae
commit
4b059201fd
2 files changed
+25
-22
No files matched your search
@@ -66,24 +66,23 @@ pub const DEFAULT_NEUTRAL_CHROMA: f64 = 12.0;
|
||||
///
|
||||
/// ## 出处:这就是「天蓝」档当前用的那个中性色相
|
||||
///
|
||||
/// 值等于 [`DEFAULT_SEED`](`#3C8DBC`)的 CAM16 色相 **239.51420577630955°**。天蓝档的
|
||||
/// 中性调色板本来就是这个色相(`Palettes::from_seed_with_neutral_chroma` 让中性色跟着种子走),
|
||||
/// 所以它是**沿用**,不是「另选一个冷调」:`Card::scheme` 换用它之后,天蓝卡的 49 个角色
|
||||
/// 必须逐值不变(`palette::card` 与 `tests/card_neutral.rs` 都钉了这条)。
|
||||
/// 值等于 [`DEFAULT_SEED`](`#3C8DBC`)的 CAM16 色相 **239.51420577630955°**。天蓝档的中性
|
||||
/// 调色板本来就是这个色相(`from_seed_with_neutral_chroma` 让中性色跟着种子走),所以它是
|
||||
/// **沿用**,不是「另选一个冷调」:`Card::scheme` 换用它之后天蓝卡的 49 个角色必须逐值不变
|
||||
/// (`tests/card_neutral.rs` 钉着)。
|
||||
///
|
||||
/// ## 为什么要有这个常量(D43)
|
||||
///
|
||||
/// 八张内置色卡原先走 TonalSpot 的「中性色也跟种子染色」,于是切卡连窗口底色一起换调子:
|
||||
/// 浅色档 `surface` 的实测 CAM16 彩度从 **1.29(rose)跨到 12.03(teal)**——tone 98 处暖相
|
||||
/// 色域装不下彩度 12,同一个「请求值 12」在暖相上只能兑现 1.29。差 9 倍的底色跳变让用户在
|
||||
/// 设置页逐张试色时觉得「每张卡都像换了个应用」。D43 的处置是:**内置色卡固定中性色相,
|
||||
/// 切卡只换强调色**;动态取色(背景图 / 壁纸)保留逐色染色,那才是用户要的 Monet 体验。
|
||||
/// 八张卡原先走 TonalSpot 的「中性色也跟种子染色」,切卡连窗口底色一起换调子:浅色档
|
||||
/// `surface` 的实测 CAM16 彩度从 **1.29(rose)跨到 12.03(teal)**——tone 98 处暖相色域装
|
||||
/// 不下彩度 12,「请求值 12」在暖相上只能兑现 1.29,9 倍跳变让用户觉得「每张卡都像换了个
|
||||
/// 应用」。D43 的处置:**色卡固定中性色相、只换强调色**;动态取色(背景图 / 壁纸)保留逐色
|
||||
/// 染色,那才是用户要的 Monet 体验。所以本常量只服务色卡路径,**不要**传给 `Seed::scheme`。
|
||||
///
|
||||
/// 所以这个常量只服务于「色卡路径」,**不要**把它传给取色路径(`Seed::scheme`)。
|
||||
///
|
||||
/// ⚠️ 换 [`DEFAULT_SEED`] 时本常量会「过期」:`neutral_hue_is_the_default_seed_hue` 用位相等
|
||||
/// (`to_bits`)钉住两者的绑定,改了种子它就当场红——那时要想清楚是「色卡跟着新默认色走」
|
||||
/// (照抄新色相)还是「色卡保持这条冷调」(把测试改成显式例外),别静默漂移。
|
||||
/// ⚠️ 换 [`DEFAULT_SEED`] 时本常量会「过期」:`neutral_hue_is_the_default_seed_hue` 用
|
||||
/// 1e-9° 容差钉住两者的绑定(**不用 `to_bits` 位相等**——色相来自跨平台有末位差的 `atan2`),
|
||||
/// 改了种子它就红——那时要想清楚是「色卡跟着新默认色走」(照抄新色相)还是「色卡保持这条
|
||||
/// 冷调」(改成显式例外),别静默漂移。
|
||||
pub const NEUTRAL_HUE_DEG: f64 = 239.514_205_776_309_55;
|
||||
|
||||
/// 调色板槽位(M3 的六条 tonal palette)。
|
||||
@@ -359,14 +358,16 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn neutral_hue_is_the_default_seed_hue() {
|
||||
// D43 的绑定器:`NEUTRAL_HUE_DEG` 必须是**出厂默认种子的中性色相**,一位不差
|
||||
// (位相等,不是近似)。天蓝卡的 49 个角色因此逐值不变;这条一旦红,说明种子换了而
|
||||
// 常量没跟着复核——要么照抄新色相(色卡跟着新默认色走),要么把这里改成显式例外。
|
||||
// D43 的绑定器。用 1e-9° 容差而非 `to_bits()` 位相等:色相来自 `atan2()`,glibc 与
|
||||
// UCRT 理论可差 1 ulp(~1e-14°),位相等会在另一个 OS 的 CI 上红;这条要抓的是「换了
|
||||
// `DEFAULT_SEED` 却没复核常量」(偏几十度)。「逐值不变」的位相等钉子在同平台的
|
||||
// `card_neutral.rs::sky_card_is_bit_identical_to_the_product_baseline`(两个算出的值
|
||||
// 互比,不涉及跨平台字面量)。
|
||||
let seed_hue = super::super::Hct::from_color(DEFAULT_SEED).hue;
|
||||
assert_eq!(
|
||||
NEUTRAL_HUE_DEG.to_bits(),
|
||||
seed_hue.to_bits(),
|
||||
"NEUTRAL_HUE_DEG = {NEUTRAL_HUE_DEG:?} 与 DEFAULT_SEED 的色相 {seed_hue:?} 不再相等"
|
||||
assert!(
|
||||
(NEUTRAL_HUE_DEG - seed_hue).abs() < 1.0e-9,
|
||||
"NEUTRAL_HUE_DEG = {NEUTRAL_HUE_DEG:?} 与 DEFAULT_SEED 的色相 {seed_hue:?} \
|
||||
相差超过 1e-9°(换默认种子时:要么照抄新色相,要么把这里改成显式例外)"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,9 @@ fn try_level(input: Option<ImageInput<'_>>, card: Card, flavor: SchemeFlavor) ->
|
||||
|
||||
// 取色方案的表面色**跟着图像种子染色**,只借当前色卡的中性彩度定浓淡(D43):
|
||||
// 这是与色卡路径刻意不同的一处——色卡固定中性色相、只换强调色,取色保留整幅染色
|
||||
// (那是用户要的 Monet 体验)。别把两条路径「统一处理」,`tests/card_neutral.rs` 有反证。
|
||||
// (那是用户要的 Monet 体验)。别把两条路径「统一处理」:这条接线的守护测试是
|
||||
// `tests/card_neutral.rs::resolved_image_scheme_keeps_tinting_from_the_seed`(走的就是
|
||||
// 本函数所在的 `resolve_source`;只测 `Seed::scheme` 的那条覆盖不到这里,复审 r1 p1-1)。
|
||||
let (scheme, adjustments) = converge(seed.scheme(flavor, card.neutral_chroma));
|
||||
let report = check(&scheme);
|
||||
if !report.is_clean() {
|
||||
|
||||
Reference in new issue
Block a user