首页
/ WezTerm Lua API 详解:`color:complement_ryb()` 与基于 RYB 色彩模型的补色计算

WezTerm Lua API 详解:`color:complement_ryb()` 与基于 RYB 色彩模型的补色计算

2026-09-10 11:43:51作者:何举烈Damon

在 WezTerm 中通过 Lua 配置生成配色方案时,常常需要根据一个基色自动推导出与之协调的对比色。color:complement_ryb() 正是为此提供的核心方法:它返回指定颜色的补色(complement),但与常规的 RGB 色环计算不同,它走的是RYB(红-黄-蓝)色彩模型——也就是画家口中"艺术家色轮"(artist's color wheel)的补色逻辑。读完本文,你将掌握该方法的用法、它与 color:complement() 的差异、背后的色相换算算法,以及如何把它用于程序化配色。

方法签名与基本行为

color:complement_ryb()
  • 返回值:一个新的 Color 对象,即当前颜色的 RYB 补色;
  • 可用版本:自 WezTerm 20220807-113146-c2fee766 版本起引入;
  • 输入输出:接受任意 Color 对象(内部以 SRGBA 存储),返回同样是 SRGBA 表示的 Color 对象。

调用方必须是 Color 对象。Color 对象可以通过 wezterm.color.parse() 解析字符串得到,也可能由 WezTerm 的各类函数与方法返回(参见 Color 对象总览)。

local wezterm = require("wezterm")

local base = wezterm.color.parse("red")      -- 基色:纯红
local comp = base:complement_ryb()           -- 基于 RYB 模型计算补色
wezterm.log_info(tostring(comp))             -- 输出补色的字符串表示

从 Lua 绑定层面看,该方法注册于 lua-api-crates/color-funcs/src/lib.rsColorWrap 用户数据类型中,底层通过 RgbaColor::complement_ryb() 实现:

methods.add_method("complement_ryb", |_, this, _: ()| Ok(this.complement_ryb()));

什么是 RYB 色彩模型

RYB(Red-Yellow-Blue,红黄蓝)是一种减色色彩模型,历史上由画家在混合颜料时总结而成。它的三个原色是红、黄、蓝,两两相混得到橙、绿、紫这三个二次色,六者共同构成"艺术家色轮"。由于颜料混色的感知特性,RYB 色环上相距 180° 的颜色,在画家眼中往往比基于 RGB(加法色)色环的补色关系更自然、更协调。

补充:color:complement_ryb() 使用 RYB 色彩模型,其补色比 RGB 模型的补色更贴近艺术家对"混合颜色"的直觉。

算法原理:HSL 色相角度在 RGB 与 RYB 之间的双向映射

原文档说明了整体流程:转换为 HSL → 将色相角换算为对应的 RYB 角度 → 旋转 180° → 再换算回 RGB → 转回 RGBA。我们可以在 color-types/src/lib.rs 中找到完整的实现来印证这一过程。

核心入口是 SrgbaTuple::complement_ryb(),它直接复用了 adjust_hue_fixed_ryb(180.)

pub fn complement_ryb(&self) -> Self {
    self.adjust_hue_fixed_ryb(180.)
}

adjust_hue_fixed_ryb 完整呈现了文档描述的四个步骤(color-types/src/lib.rs#L608-L617):

pub fn adjust_hue_fixed_ryb(&self, amount: f64) -> Self {
    let (h, s, l, a) = self.to_hsla();        // 1. 转 HSL
    let h = rgb_hue_to_ryb_hue(h);            // 2. RGB 色相角 → RYB 色相角
    let h = normalize_angle(h + amount);      // 3. 旋转 180°,并归一化到 [0, 360)
    let h = ryb_huge_to_rgb_hue(h);           // 4. RYB 色相角 → RGB 色相角
    Self::from_hsla(h, s, l, a)               // 5. 用原饱和度/亮度重建 RGBA
}

注意:旋转只改变色相,饱和度(S)与明度(L)原样保留,因此补色的明暗、鲜艳程度与基色保持一致,只在对立的色相位置上。

色相映射表:分段线性换算

RGB 与 RYB 的色相角并非简单线性对应,WezTerm 采用分段线性映射。正方向 rgb_hue_to_ryb_huecolor-types/src/lib.rs#L659-L675)按 7 个区间换算:

RGB 色相区间(°) RYB 色相区间(°)
0 – 35 0 – 60
35 – 60 60 – 122
60 – 120 122 – 165
120 – 180 165 – 218
180 – 240 218 – 275
240 – 300 275 – 330
300 – 360 330 – 360

例如,RGB 色环中红在 0°、黄在 60°,而 RYB 色环中红被压缩到 0°、黄被推至 60°、绿大致对应 122° 附近……这套表在视觉上把"画家直觉"量化进了程序。

逆变换 ryb_huge_to_rgb_huecolor-types/src/lib.rs#L679-L695)则执行完全相反的分段映射,保证"转过去再转回来"不会破坏色相。每个区间内通过 map_range 做线性插值,normalize_anglecolor-types/src/lib.rs#L705-L711)负责把旋转后的角度收拢到 [0°, 360°),从而支持负角度与超过 360° 的角度自动回绕。

complement_ryb()complement() 的区别

原文档特意指出它与 color:complement() 互为参考。两者的差异就在于旋转所基于的色环模型

方法 色相换算 计算结果特点
complement() 直接在 HSL 色相角上加 180°(color-types/src/lib.rs#L585-L587 RGB 模型补色,如红的补色偏向青色系
complement_ryb() 先换算到 RYB 角度,旋转 180° 后再换回 RGB RYB 模型补色,更贴近艺术家直觉,如红的补色是绿色系

以纯红(#ff0000)为例:RGB 补色约为青色 #00ffff(色相 180°),而 RYB 补色经映射后更接近绿色系。这正体现了两种色彩模型对"补色"的认知差异。

实战:把补色用于程序化配色

complement_ryb() 最常见的场景是在 wezterm Lua 配置中程序化生成配色方案,例如以主色调为基准自动推导前景色、强调色或分隔色:

local wezterm = require("wezterm")

-- 用主色调的 RYB 补色作为强调色,保证视觉协调
local accent = wezterm.color.from_hsla(210, 0.8, 0.6, 1.0)
local accent_complement = accent:complement_ryb()

return {
  colors = {
    accent = tostring(accent_complement),
  },
}

配合 wezterm.color.from_hsla()color:adjust_hue_fixed_ryb() 等方法,可以在不硬编码任何色值的前提下,让整套配色随一个基准色自动衍生:

  • adjust_hue_fixed_ryb(180) 得到补色,与 complement_ryb() 等价;
  • triad() 三个色相各隔 120°;
  • square() 四个色相各隔 90°;
  • 再用 color:saturate()color:lighten() 等微调明度与饱和度,即可生成完整的色板。

小结

  • color:complement_ryb() 返回基于 RYB 艺术家色轮的补色,由 color-types/src/lib.rsadjust_hue_fixed_ryb(180.) 实现;
  • 算法本质是:HSL 化 → RGB/RYB 色相分段线性互转 → 旋转 180° → 重建 RGBA;
  • 需要严格"颜色科学"意义的补色时用 color:complement(),需要画家直觉的协调色时用 complement_ryb()
  • 它是 WezTerm 程序化生成配色方案(Color 对象方法集)中的重要一环,适合在 Lua 配置中动态推导协调色。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.16 K
2.78 K
kernelkernel
deepin linux kernel
C
34
18
docsdocs
暂无描述
Markdown
904
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
934
1.86 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
862
1.36 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.96 K
1.03 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.38 K
1.47 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
535
606
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
549
398
leetcodeleetcode
🔥LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解
Markdown
77
23