---
name: claude绘图
description: Claude 绘图 / Claude Drawing —— 不借助任何生图模型，由 Claude 用代码一笔一笔「画」出图片（程序化绘画）。内置四十三种画风：中国水墨、水彩、剪纸拼贴、韩国彩铅、日本动漫、编辑风手绘（Riso）、油画厚涂（梵高式流向笔触+颜料浮雕打光）、浮世绘木版画（晕色、木纹、墨线主版、青海波）、像素风（低分辨率+Bayer 抖动+像素字体）、黏土定格（高度图捏出的彩泥+影棚打光）、蓝晒（普鲁士蓝日光晒图，植物剪影透光）、十字绣（Aida 布十字绣+回针绣+缎面绣+法式结）、复古仪器面板（60 年代收音机/仪器正面：柚木、拉丝铝、旋钮、刻度窗、指示灯）、贴纸拼贴·小票（模切乙烯贴纸、热敏小票、和纸胶带、吊牌、橡皮章）、实验笔记本·贴纸（线圈方格本、铅笔图表、荧光笔、红笔圈、便利贴）、黑板板书（墨绿石板、粉笔颗粒、板擦残影、示意图与公式）、赛博朋克（雨夜霓虹街道、玻璃管霓虹招牌、全息广告、湿路面倒影）、卡通手绘（蓝铅笔稿、毛笔线、错位平涂、赛璐璐阴影、逐帧抖线）、等轴 2.5D（正等轴微缩模型、一个太阳照出三面明暗、悬浮数据卡）、单线画（一根不断开的线一笔画完、唯一点睛色）、柔光 3D（光线追踪的糖果色小球海和鼓鼓的软字、景深）、形变动画（一条轮廓依次变形、洋葱皮残影、缓动曲线）、报刊拼贴（牛皮纸、手撕旧报纸、网点老照片、勒索信拼贴字）、弥散玻璃（弥散渐变、磨砂玻璃卡片界面）、包豪斯几何（三原色几何、丝网印刷海报）、复古 Synthwave（切口落日、霓虹网格、镀铬字、录像带质感）、拼豆（钉板上的熔珠小管、熨烫熔合）、岩画（沙漠漆上凿出的凹坑图形、新旧凿痕、剥落）、古埃及墓室壁画（灰泥墙、红格起稿、分栏叙事、象形文字、剥落）、罗马马赛克（石子与玻璃沿轮廓一排排铺、灰缝、燕尾铭牌）、彩色玻璃花窗（哥特尖拱窗、通体着色玻璃、grisaille 彩绘与银染、铅条、透光）、泥金手抄本（羊皮纸、鹅毛笔哥特体、朱红标题、打磨金箔首字母）、达·芬奇手稿（铁胆墨水、左手排线、红粉笔、镜像手写、机械分解图）、剪影（黑纸剪出的侧影小像、薄金粉、椭圆金框）、凸版印刷海报（木活字、红黑双色错版、木刻插图）、苏联构成主义（红黑两版、斜条与楔形、西里尔大字、网点照片拼贴）、装饰艺术 Art Deco（1930 年代喷枪流线型海报、交替射线、阶梯高楼、金色 Deco 字）、黄金时代漫画（毛笔墨线、Ben-Day 网点、四色错版、新闻纸）、波普丝网（多格撞色平涂 + 错位的照相黑版）、ASCII 字符画（行式打印机、绿条连续纸、叠打）、低多边形（1999 年代 3D：平面着色、仿射贴图、逐顶点雾、15 位色抖动）、喷漆模板涂鸦（混凝土墙上多层卡纸模板喷绘、雾化与滴痕）、刺绣徽章（牛仔布上的机绣徽章：填充绣、缎面绣、锁边）。用户说「claude绘图」「用代码画」「你自己画」「不用生图模型画」「程序化绘画」，或点名以上任一画风（含黏土、彩泥、定格动画、蓝晒、晒图、十字绣、刺绣、复古面板、老式收音机、贴纸、小票、收据、手帐拼贴、实验笔记本、方格本、荧光笔、便利贴、黑板、板书、粉笔、赛博朋克、霓虹、雨夜街道、卡通、手绘卡通、逐帧手绘、抖线、等轴、2.5D、微缩模型、单线画、一笔画、线条动画、柔光 3D、3D 渲染、C4D 风、软糖字、小球海、形变、变形动画、报刊拼贴、剪报、达达、勒索信字、网点印刷、弥散渐变、玻璃拟态、毛玻璃、包豪斯、几何构成、丝网印刷、Synthwave、蒸汽波、合成器浪潮、80 年代复古、拼豆、拼拼豆、熔珠、熨豆、豆豆画、钉板、烫豆、岩画、岩刻、凿刻、石刻、沙漠漆、史前壁刻、大角羊、古埃及、埃及壁画、墓室壁画、法老时代、象形文字、尼罗河、底比斯、罗马马赛克、马赛克镶嵌、镶嵌画、石子拼画、地砖画、古罗马地板、彩色玻璃、彩绘玻璃、花窗、玻璃花窗、教堂花窗、哥特花窗、铅条玻璃、泥金手抄本、手抄本、彩饰手抄本、中世纪手稿、羊皮纸、哥特体、花体首字母、泥金、贴金、星盘、达芬奇、达·芬奇、达芬奇手稿、手稿风、文艺复兴手稿、发明手稿、镜像字、镜像书写、扑翼机、红粉笔、钢笔排线、机械草图、分解图、剪影、剪影肖像、侧影、侧面像、黑纸剪影、剪影小像、椭圆金框、乔治时代肖像、摄政时期肖像、凸版印刷、活版印刷、木活字、铅字海报、马戏团海报、复古海报、老海报、19 世纪海报、双色套印、错版、套色错位、木刻插图、构成主义、苏联海报、苏联构成主义、俄国先锋派、罗德琴科风、红黑海报、照片蒙太奇、照片拼贴海报、西里尔字、装饰艺术、装饰风、流线型、流线型海报、1930 年代海报、旅行海报、铁路海报、火车海报、喷枪画、喷笔画、阶梯高楼、射线背景、盖茨比风、黄金时代漫画、老漫画、复古漫画、美漫封面、漫画封面、Ben-Day 网点、本戴点、网点上色、四色印刷、四色错版、新闻纸、对白框、拟声字、1940 年代漫画、波普、波普艺术、波普丝网、沃霍尔风、丝网版画头像、撞色头像、多格重复头像、六宫格撞色头像、ASCII、字符画、字符艺术、文字画、行式打印机、绿条纸、连续打印纸、针孔打印纸、老电脑打印、叠打、低多边形、低面数、低模、多边形风、千禧年 3D、90 年代 3D、复古 3D 游戏、老游戏截图、PS1 风、N64 风、平面着色、线框、游戏 HUD、飞行游戏、穿环、喷漆、模板涂鸦、镂空模板、喷漆模板、模板喷绘、街头涂鸦、街头艺术、墙绘、滴漆、班克西风格、刺绣徽章、徽章、布章、臂章、刺绣贴、绣标、锁边、牛仔外套徽章、户外徽章、营地徽章、弧形条章），或 "draw it yourself", "paint with code", "procedural painting", "watercolor / collage / colored pencil / anime / editorial / impasto oil / ukiyo-e / pixel art / clay / claymation / cyanotype / sun print / cross-stitch / embroidery / retro instrument panel / vintage radio / sticker collage / receipt / lab notebook / graph paper / chalkboard / blackboard / cyberpunk / neon city / cartoon / hand-drawn animation / isometric / 2.5D / continuous line / one-line drawing / soft 3D / 3D render / puffy letters / ball pit / shape morph / morphing / newspaper collage / Dada / ransom note / halftone / glassmorphism / aurora gradient / Bauhaus / geometric poster / screen print / synthwave / retrowave / outrun / perler beads / hama beads / artkal / fuse beads / melty beads / pegboard beads / petroglyph / rock art / rock carving / desert varnish / Egyptian tomb painting / ancient Egypt / hieroglyphs / Theban tomb / Roman mosaic / floor mosaic / tesserae / opus vermiculatum / Pompeii mosaic / stained glass / leaded glass / church window / Gothic window / grisaille / illuminated manuscript / medieval manuscript / book of hours / gold leaf / illuminated initial / blackletter / vellum / astrolabe / da Vinci notebook / Leonardo codex / Renaissance sketchbook / mirror writing / iron-gall ink / red chalk / sanguine / ornithopter / exploded view / inventor's sketch / silhouette / silhouette portrait / cut-paper profile / shade portrait / Georgian portrait / Regency portrait / oval gilt frame / letterpress / wood type / playbill / circus poster / Victorian poster / two-colour misregistration / woodcut poster / constructivism / constructivist poster / Soviet avant-garde / Russian avant-garde / Rodchenko style / photomontage poster / art deco / streamline moderne / 1930s travel poster / railway poster / airbrush poster / sunburst rays / Gatsby style / golden age comic / vintage comic book / comic cover / Ben-Day dots / four-color printing / newsprint / speech balloon / pulp cover / pop art / Warhol-style / pop silkscreen / silkscreen portrait / repeated pop portrait grid / ASCII art / text art / typewriter art / line printer / greenbar / fanfold paper / tractor feed / overstrike / printer plot / low poly / low-poly / retro 3D / 90s 3D game / PS1 style / N64 style / software rasterizer / flat shading / affine texture mapping / vertex fog / game HUD / stencil / stencil graffiti / spray paint stencil / street art / drips and overspray / Banksy-style stencil / embroidered patch / embroidery patch / iron-on patch / sew-on patch / merit badge / camp badge / merrow border / rocker patch / denim jacket patches without an image model" 时使用；也用于需要逐步画出（draw-on）动画的插画。单独说「剪纸」指剪纸拼贴、「刺绣」指十字绣、「丝网印刷 / screen print」指包豪斯几何；「打马赛克」是打码，不是马赛克画风。
---

# Claude 绘图

用 Python（只依赖 numpy + Pillow，系统自带的 `python3` 就能跑）按笔、墨、颜料、纸的物理规律「画」图，不调用任何生图模型。
- **构图可控**：每一笔都是算出来的，构图、留白、点睛色的位置都精确可控。
- **结果可复现**：固定随机种子，每次画出同一幅画。
- **适合做动画**：可以输出分阶段快照，做成「一幅画被逐步画出来」的动画；生图模型只能给一整张画。

## 画风与范例（质量基准）

| 画风 | 库 | 范例 | 耗时 |
|---|---|---|---|
| 水墨 | `lib/inkpaint.py` · `Painting` | `examples/bawansiqian.py` 八万四千法门；`examples/moon_river.py` 月印万川（烘云托月、孤舟、芦苇） | 约 4 秒 |
| 水彩 | `lib/watercolor.py` · `Watercolor` | `examples/watercolor_autumn.py` 秋日湖畔（秋树罩染、湖面倒影、红色小舟）；`examples/watercolor_washes.py` 水彩底纹（大片定向晕染、干边、回流水渍、颗粒、飞溅，中间留白，给讲解片当背景、上面叠界面卡片） | 约 15 秒 / 4 秒 |
| 剪纸拼贴 | `lib/papercut.py` · `Collage` | `examples/papercut_balloons.py` 热气球小镇（条纹热气球、笑脸太阳、纸云、小房子） | 约 30 秒 |
| 韩国彩铅 | `lib/colorpencil.py` · `ColorPencil` | `examples/colorpencil_dessert.py` 午后甜点（草莓蛋糕、红茶、草莓） | 约 17 秒 |
| 日本动漫 | `lib/anime.py` · `Anime` | `examples/anime_summer.py` 夏空（积雨云、乡间公路、电线杆、草帽女孩背影） | 约 30 秒 |
| 编辑风手绘 | `lib/editorial.py` · `Editorial` | `examples/editorial_ideas.py` 灵感生长（浇水长出灯泡的概念插画） | 约 11 秒 |
| 油画厚涂 | `lib/oilpaint.py` · `OilPainting` | `examples/oil_wheatfield.py` 麦田星空（旋转的星空、麦田、柏树、乌鸦） | 约 2 秒 |
| 浮世绘木版画 | `lib/ukiyoe.py` · `Ukiyoe` | `examples/ukiyoe_fuji.py` 富士曙（晕色天空、富士、云带、青海波、帆船、崖松） | 约 7 秒 |
| 像素风 | `lib/pixelart.py` · `PixelArt` | `examples/pixel_rainy_cafe.py` 雨夜咖啡店（霓虹、路灯、雨、倒影、猫） | 约 0.1 秒 |
| 黏土定格 | `lib/clay.py` · `Clay` | `examples/clay_lighthouse.py` 灯塔岛（手指抹开的天空、条纹灯塔、喷水的鲸鱼、搓条浪花、小帆船） | 约 6 秒 |
| 蓝晒 | `lib/cyanotype.py` · `Cyanotype` | `examples/cyanotype_botanicals.py` 蓝晒植物（蕨叶、银杏、蒲公英、飘散的种子、白色手写标注） | 约 6 秒 |
| 十字绣 | `lib/stitch.py` · `Stitch` | `examples/stitch_sampler.py` 家（H♥ME 字母、缎面绣爱心、小屋、苹果树、松树、花边、缝上的布标） | 约 20 秒 |
| 复古仪器面板 | `lib/panel.py` · `Panel` | `examples/panel_radio.py` Aurora 64 收音机（柚木机壳、喇叭布、背光刻度窗、琴键、魔眼管、拨杆、旋钮） | 约 7 秒 |
| 贴纸拼贴 · 小票 | `lib/sticker.py` · `Sticker` | `examples/sticker_market.py` 周末市集（热敏小票、模切贴纸：酸种面包/传家番茄/郁金香花束/咖啡豆、贴纸大字、波浪边促销贴、麻绳吊牌、和纸胶带、「已付」橡皮章） | 约 3 秒 |
| 实验笔记本 · 贴纸 | `lib/notebook.py` · `Notebook` | `examples/notebook_brewing.py` 咖啡萃取实验（线圈方格笔记本、铅笔表格与折线图、排线标出最佳区间、荧光笔、没闭合的红笔圈、便利贴结论、模切贴纸、标签机日期、桌上的六棱铅笔） | 约 3 秒 |
| 黑板板书 | `lib/chalk.py` · `Chalkboard` | `examples/chalk_lesson.py` 为什么天空是蓝的（墨绿石板、半擦掉的上节课残影与板擦痕、越往下越厚的粉笔灰；白黄粉蓝粉笔写的标题、太阳→大气层→眼睛示意图、长短波浪线、手写 ∝ 与圈出的 1/λ⁴、光谱条与散射曲线、带缺口的「小结」框；木框和粉笔槽里的粉笔、板擦） | 约 5 秒 |
| 赛博朋克 | `lib/cyberpunk.py` · `Cyberpunk` | `examples/cyberpunk_neon_street.py` 霓虹不夜城 · Neon District（雨夜街道峡谷、真玻璃管霓虹竖招牌（坏管与闪烁管）、背光灯箱、过街天桥「不夜城」、全息海月水母广告、电线、飞车光轨、井盖蒸汽、透明伞背影、湿路面与水洼倒影、胶片颗粒与一道撕裂扫描线） | 约 10 秒 |
| 卡通手绘（逐帧手绘） | `lib/cartoon.py` · `Cartoon` | `examples/cartoon_toaster.py` 早安吐司（薄荷绿吐司机笑着弹出两片举手的吐司、「叮！」爆炸框、盘子上打瞌睡的化黄油、窗外日出、墙上 7 点的钟；左侧 ①按下拉杆 ②电热丝烧红 3 分钟 ③弹起来 的图解；蓝铅笔稿留底、毛笔线、错位平涂、赛璐璐阴影、蜡笔天空与烤边、网点橱柜、抖线） | 约 4 秒 |
| 等轴 2.5D | `lib/isometric.py` · `Isometric` | `examples/isometric_weather_island.py` 岛上的气象站（漂浮的分层底座、一格一格的倒角地砖与台地、带双道浪花的海；观测场里的百叶箱、雨量筒、带风杯和风向标的风杆；看守小屋与卫星天线、太阳能板、石板路、栈桥小船、风袋、浮标、开花灌木；探空气球和平底云；四张悬浮数据卡用细引线指向各自仪器，地面上一个指北针） | 约 5 秒 |
| 单线画 | `lib/lineart.py` · `LineArt` | `examples/lineart_paper_plane.py` 从这扇窗到那扇窗（一根不断开的金线：圆树、小屋、从窗口穿墙飞出的纸飞机航迹与顶部翻圈、飞镖形纸飞机穿墙飞进对面小屋的窗；窗子亮起是全画唯一的点睛色；字距拉开的衬线标题） | 约 6 秒 |
| 柔光 3D | `lib/soft3d.py` · `Soft3D` | `examples/soft3d_rise.py` 浮出（糖果色小球海里顶出鼓鼓的软字 rise：被挤开的球堆在字脚、几颗骑在字肩上、几颗滚落，i 的点是一颗黄球；天光穹顶、柔光箱主光、粉色轮廓光、环境光遮蔽、软阴影、次表面色调、景深） | 约 46 秒 |
| 形变动画 | `lib/morph.py` · `Morph` | `examples/morph_water_cycle.py` 一滴水的旅程（一条 256 点轮廓线依次变成水滴→云→雪花→雪山→河→海浪，六块纯色背景随之切换；洋葱皮残影、挤压拉伸、虚线运动轨迹、中间帧标出对应点、缓动曲线时间轴） | 约 1 秒 |
| 报刊拼贴 | `lib/newscollage.py` · `NewsCollage` | `examples/newscollage_curiosity.py` 好奇心周刊 · 拆开看看（牛皮纸底、手撕旧报纸（程序生成的假文字栏）、被剪刀剪开并掀起上半的网点印刷闹钟照片、飞出的齿轮 / 发条 / 红色网点摆轮 / 螺丝各自剪下并配打字标签和引线、大红纸圆、勒索信拼贴字「拆开看看？」和 WHAT MAKES IT TICK、刊头、黑色邮戳、红色「附零件图」印章、美纹纸胶带） | 约 3 秒 |
| 弥散玻璃 | `lib/aurora.py` · `Aurora` | `examples/aurora_morning.py` 晨间计划（日出色弥散渐变与极光光带、光泽小球；磨砂玻璃卡片层叠：晨间计划时间线（3/5 完成，进行中那一行是玻璃叠玻璃）、专注倒计时圆环、光泽太阳躲在玻璃云后的天气卡、勿扰开关与白噪音滑块、近 7 天专注柱状图、9:00 站会提醒胶囊） | 约 2 秒 |
| 包豪斯几何 | `lib/bauhaus.py` · `Bauhaus` | `examples/bauhaus_form_colour.py` 形与色 · Form & Colour（奶油色纸上的丝网印刷讲座海报：黄三角、红方、蓝圆站在粗黑地线上，60° 弧、直角框、挖空的圆心和半径，下面大字角数 3 / 4 / 0；「形与色」大标题、挖空字的黑条论点「角越尖，色越亮」；构成网格、套准十字、裁切线、色标条、铅笔版号） | 约 2 秒 |
| 复古 Synthwave | `lib/synthwave.py` · `Synthwave` | `examples/synthwave_coastline.py` 海岸线 1987（横条切口的渐变落日沉入海面、倒影碎成一条条光带、线框小岛与线框山脉、霓虹网格地面、霓虹边线的海岸公路、灭点处亮灯的小城、带落日轮廓光的棕榈剪影、驶向城市的尾灯、镀铬大字 COASTLINE 与霓虹手写 Last Sunset、录像机 PLAY 与日期屏显、色度渗色、跟踪噪带和扫描线） | 约 4 秒 |
| 拼豆 | `lib/perler.py` · `Perler` | `examples/perler_strawberry_coaster.py` 草莓杯垫（方格图纸上的草莓图样与图例，铅笔勾掉已摆的颜色；透明方钉板上摆到一半：草莓摆完、天蓝底色一行行往下铺，镊子夹着下一颗悬在空钉上，旁边散豆；九格分色收纳盒；熨平的圆杯垫：豆子熔成一片蜡质平面、孔缩小、外沿扇贝形，压着揭下的熨烫纸） | 约 9 秒 |
| 岩画（凿刻砂岩） | `lib/petroglyph.py` · `Petroglyph` | `examples/petroglyph_migration.py` 迁徙季（带沙漠漆的砂岩岩面：一群大角羊朝同一方向往上走，一串偶蹄印通向同心圆水源，弓手和举投矛器的猎人等在后面；新月和一个月的计日刻痕、螺旋太阳、岩檐下一大一小两只手印；新、中、旧三档凿痕，几乎被漆盖回的旧符号；渗漆的裂缝、鲜橙色剥落疤、壳状地衣；左上低角度侧光） | 约 10 秒 |
| 古埃及墓室壁画 | `lib/tomb.py` · `TombPainting` | `examples/tomb_harvest.py` 尼罗河丰收（底比斯墓室的一面墙，三栏讲一件事：犁地播种（并轭的牛、扶犁人、撒种人、挥锄人），割二粒小麦（弯腰的割麦人、拾穗的女人、挂水囊的无花果树），书吏点数粮袋（蹲坐的书吏、堆成 5-4-3 的 12 袋粮和上方的象形数字 12、用量斗倒粮的人）；按身份放大的庄园总管、伪象形文字栏、凯凯尔饰带、墙脚的尼罗河；剥落处露出红格和红稿，灰泥脱落、裂缝、潮痕、烟熏） | 约 4 秒 |
| 罗马马赛克 | `lib/mosaic.py` · `Mosaic` | `examples/mosaic_harbor.py` 港口渔获 · The Day's Catch（赭红起稿的灰浆床上铺约一万六千块石子与玻璃：黑白奔浪纹边框、火焰灯塔、船首画眼的渔船和鼓起的方帆、挑在杆上的渔网、把鱼从网里拖走的章鱼、游鱼和海鸥；燕尾铭牌 CAPTVRA · DIEI / ET POLYPVS FVR「今日渔获——以及章鱼小偷」；人物沿轮廓一排排铺，背景平铺并留光环；脱落处露出石子方坑，沉降裂缝，灰缝积灰） | 约 12 秒 |
| 彩色玻璃花窗 | `lib/stainedglass.py` · `StainedGlass` | `examples/stainedglass_seasons.py` 四季之窗 · Window of the Seasons（石墙上四扇哥特尖拱窗，同一棵树的春夏秋冬：春花与燕子、夏天的苹果和一窝雏鸟、秋天金红树冠和离开的雁阵、冬天积雪的枝和知更鸟，太阳高度随季节变；VER / AESTAS / AVTVMNVS / HIEMS 银染题字带；铅条与焊点、横铁条、一处补过的裂片，窗侧斜面和窗台上的彩色光） | 约 4 秒 |
| 泥金手抄本 | `lib/illuminated.py` · `Illuminated` | `examples/illuminated_starchart.py` 星辰之书 · Liber Stellarum（暗色书桌上摊开的天文书。左页「行星的次序」：打磨贴金方框里的玫瑰色 Q 首字母，字腔里是夜空和观星塔；鹅毛笔哥特体伪拉丁正文、朱红标题、长出常春藤花枝的条形边框、一幅诸天圆图。右页「怎样量一颗星的高度」：蓝色首字母 O 配红色花笔卷须，按纬度 48° 投影的尺规星盘，规尺瞄向页边的贴金星。羊皮纸毛孔、针孔与打格线、背面透字、破洞、狐斑、金箔剥落露出红色底料） | 约 9 秒 |
| 达·芬奇手稿 | `lib/codex.py` · `Codex` | `examples/codex_ornithopter.py` 扑翼机（裱在卡纸上、缺一角的泛黄帘纹纸；一串飞鸟画出一次振翅，红粉笔鸢翼写生和一根大羽毛；中间是蝙蝠翼扑翼机仰视图：右翼用左手「\」排线画完，左翼只起了头、露着铅笔稿；尖笔圆规画的比例圆，曲柄、灯笼齿轮、冠齿轮、滑轮的传动分解图，腕关节特写，划掉的废稿；右到左的镜像伪文笔记、墨点、霉斑、水渍） | 约 8 秒 |
| 剪影 | `lib/silhouette.py` · `Silhouette` | `examples/silhouette_family.py` 剪影小像（木版印花条纹墙纸上，挂镜线铜钩的绞丝绳吊着三幅椭圆金框剪影：中间是戴鸵鸟羽毛宽檐帽、螺旋垂卷的女主人，右边一艘满帆回家的双桅横帆船，左边坐在流苏垫子上望着她的猫；单独剪下的羽枝、睫毛、胡须和缆绳，剪空的猫眼和蕾丝孔；薄金粉、铁胆墨圆体题签、玻璃背面的金线圈、凸面玻璃反光、棱顶磨出红色底漆的旧金框） | 约 3 秒 |
| 凸版印刷海报 | `lib/letterpress.py` · `Letterpress` | `examples/letterpress_circus.py` 马戏团来了（1890 年代红黑两色马戏团海报：左栏每行木活字排满版心——THE GRAND TRAVELLING、带投影的红色大字 CIRCUS、宋体黑木活字「马戏团来了」、星号节目单；右边木刻：走钢丝的舞者端着平衡杆，下面戴非斯帽的大象踩在条纹鼓上扬鼻致意，40 FT. 尺寸线；红版色块与黑版轮廓错开几像素；三折折痕裂墨、贴上的日期条 SATURDAY · MAY 17、钉孔锈斑、泛黄与霉斑） | 约 6 秒 |
| 苏联构成主义 | `lib/constructivism.py` · `Constructivism` | `examples/constructivism_radio.py` 无线电 · РАДИО（虚构的 1920 年代无线电爱好者杂志封面，红黑两版：仰拍的双曲面网格广播塔印成网点、叠在红色圆盘上，塔尖射出红色楔形和越传越细的黑色波前，送进剪刀剪下的网点照片——带号角喇叭的电子管收音机；黑色斜条里反白 СЛУШАЙТЕ ВЕСЬ МИР（收听全世界），粗体压缩西里尔大字 РАДИО，三个编号标注；对折两次的折痕裂墨、霉斑、水渍潮线、图钉锈孔） | 约 6 秒 |
| 装饰艺术（Art Deco） | `lib/artdeco.py` · `ArtDeco` | `examples/artdeco_express.py` 夜行快车 · Night Express（1930 年代喷枪流线型铁路海报：午夜蓝长渐变天空、满月外一圈交替射线、探照灯；雾中远城和阶梯退台高楼，钟楼的钟停在 11:40；河面把城市和月亮反射成横向波纹；栗红流线型列车从城里驶上拱桥迎面而来，金色速度线收拢在车鼻上，头灯照亮铁轨；Deco 金字 NIGHT EXPRESS、阶梯角双金线边框；全画没有一根描边，形体全靠明暗） | 约 12 秒 |
| 黄金时代漫画 | `lib/comic.py` · `ComicCover` | `examples/comic_rocket.py` 火箭小队 No. 3（1940 年前后的报摊漫画封面：朝灭点挤出的立体刊名 ROCKET SQUAD、价格框和黄色旁白框；暮色天空分档网点、大月亮；红色火箭起飞，June 舰长指着月亮喊「NEXT STOP -- THE MOON!」，后座小狗 Pip 戴着护目镜；没赶上的机修工 Sparky 吊在绳梯上喊「HEY!! WAIT FOR ME!!」；拟声字 WHOOOSH!；毛笔墨线与羽状排线、Ben-Day 网点、三色版错位、泛黄新闻纸、书脊裂纹和生锈订书钉） | 约 5 秒 |
| 波普丝网 | `lib/popart.py` · `PopSilkscreen` | `examples/popart_cat_moods.py` 猫的六种心情（白底漆帆布用胶带隔出 3×2 六格，同一只虎斑猫按顺序讲一件小事：歪头好奇 → 馋得吐舌头 → 吃到了眯眼笑 → 被抓包瞪圆眼 → 压耳哈气 → 歪头睡着；每格先手涂一套撞色、描得很松，再刮印同一块照相黑版，中间调成 45° 粗网点；六格放版的位置、角度和墨量各不相同：糊版、缺墨、横刮、印了两次留灰影、干版露底） | 约 3 秒 |
| ASCII 字符画（行式打印机） | `lib/lineprinter.py` · `LinePrinter` | `examples/lineprinter_launch.py` 发射记录（桌上一整张 1970 年代 132 列绿条连续纸，两侧导孔、微孔撕线；左边整幅火箭发射的字符画：尖拱头锥、. : + % # 侧光箭身、叠打 #@ 的滚转标记、从喷口往下变宽的尾焰亮柱扎进翻滚的烟云，旁边是桁架勤务塔、塔吊、远处水塔、清晨太阳和人字形鸟群；右栏是事件日志、高度-时间打印机绘图和通道状态表；鼓式打印机的上下跳字、弱锤淡列、色带渐淡；读的人用红圆珠笔打勾、圈点、写了 on plan） | 约 2.3 秒 |
| 低多边形（1999 年代 3D） | `lib/lowpoly.py` · `LowPoly` | `examples/lowpoly_canyon.py` 峡谷飞行 · Canyon Run（一帧虚构的 1999 年飞行游戏：小特技飞机在沙漠峡谷的右弯处压坡度，对准九个金环里的第五个，第六个挂在天然石拱下；阶梯状分层岩壁、起伏小面的河、十字插片杜松、雾里化开的方山；半透明螺旋桨盘、金环闪光、镜头光晕；384×216 帧缓冲、15 位色 4×4 有序抖动、无平滑放大 5 倍；HUD：金环计数 04/09、单圈时间、阶梯速度条、赛道小地图） | 约 0.2 秒 |
| 喷漆模板涂鸦 | `lib/stencil.py` · `Stencil` | `examples/stencil_kite.py` 放风筝 · Hold On（木纹模板清水混凝土墙：木纹、浆棱、对拉螺栓孔、锈水雨痕、返潮泛碱、发丝裂缝；三张卡纸模板白 → 灰 → 黑喷出的小孩：毛线帽、羽绒服、往前飘的条纹围巾，身子后仰攥着线轮；徒手喷的风筝线连到左上角的红色菱形风筝；同一张小模板转着角度喷的燕子和树叶；带桥的 HOLD ON 模板字；清晰核心、外溢雾化、飞沫、滴痕；滚筒灰漆盖掉的旧签名、被水枪冲淡的粉色签名） | 约 6 秒 |
| 刺绣徽章 | `lib/patch.py` · `Patch` | `examples/patch_camping.py` 三晚露营（牛仔夹克后背，过肩缝压着双道明线，一晚一枚徽章：第一晚是热切缎面边的拱形异形章——日落分层天空、远山、湖面倒影、亮灯的帐篷；第二晚是金色锁边圆章——雪峰、松林、营火与火星、弯月，缎面字 HIGH CAMP / NIGHT 2，上方弧形条章 THREE NIGHTS OUT；第三晚是正在手缝的指南针章，针和线还留在牛仔布上；一条刺子绣虚线把三枚徽章串成路线） | 约 6 秒 |

各画风共用 `lib/core.py` 里的底层工具：噪声、模糊、样条曲线、多边形遮罩、有机轮廓 `blob_pts`、毛笔 `bristle_stroke`、中文字体查找；新四种还用到补零平移 `shift`、文字遮罩 `text_mask`、西文字体查找 `latin_font`/`load_font`，以及高度图打光 `height_normals`、`height_shadow`（沿光线步进的投影）、`ambient_occlusion`。

**用户没有指定画风时怎么选**：
- 禅意、古典、山水 → 水墨；
- 清新风景、花卉 → 水彩；
- 童趣、温暖、讲故事 → 剪纸拼贴；
- 甜点、小物、日常可爱 → 韩国彩铅；
- 青春、夏日、天空、背景美术 → 日本动漫；
- 观点、概念、商业文章配图 → 编辑风手绘；
- 浓烈、有笔触质感、名画感 → 油画厚涂；
- 日式古典、海浪、富士、东方装饰感 → 浮世绘；
- 复古游戏、夜景霓虹、小尺寸动画 → 像素风；
- 童趣立体、讲故事、手作感、定格动画 → 黏土定格；
- 植物、标本、自然科学、复古工艺感的蓝色海报 → 蓝晒；
- 家、温馨、手作礼物、贺卡、名字和字母 → 十字绣；
- 设备、仪表、音响收音机、复古科技与产品感 → 复古仪器面板；
- 清单、账单、价格、购物、市集、活动海报、轻松但成熟的讲解片封面 → 贴纸拼贴 · 小票；
- 实验记录、数据对比、复盘笔记、讲解片里的「算账 / 结论」页 → 实验笔记本 · 贴纸；
- 讲课、知识点、公式推导、原理示意图、讲解片里的「板书 / 课堂」页 → 黑板板书；
- 夜景、城市、雨、霓虹、电影感氛围、讲解片的「未来 / 科技 / 城市」封面 → 赛博朋克（要复古小尺寸或像素动画仍用像素风）；
- 可爱的拟人小物件、日常小事讲故事、带表情的角色、讲解片里轻松的「步骤 / 原理」图解、要逐帧抖线的动画 → 卡通手绘（要立体手作感用黏土定格，要纸片感用剪纸拼贴）；
- 小世界、城市 / 园区 / 工厂 / 校园示意，系统或流程的「微缩模型」图解，围着场景放数据卡的信息图，讲解片的「全景 / 系统概览」页 → 等轴 2.5D（要霓虹夜景用赛博朋克；要复古小尺寸用像素风）；
- 高级克制、极简、品牌感封面、要看「一笔画出来」的过程、讲一段路线或旅程 → 单线画（深蓝底金线或奶油底墨线，只一个点睛色）；
- 产品感、软萌立体、糖果色、MG 片头大字、「3D 渲染」、讲解片封面的立体标题 → 柔光 3D（要手作、捏泥的质感仍用黏土定格）；
- 过程、变化、循环、「从 A 变成 B」的小故事，讲解片的转场、片头和「演变」页 → 形变动画（要真的动起来，用 `Morph.at` 逐帧出图）；
- 杂志封面、观点海报、达达 / 复古拼贴、「拆开看看 / 里面有什么」类讲解页、需要老照片质感又不能用真人照片 → 报刊拼贴（要童趣温暖的彩纸拼贴仍用剪纸拼贴）；
- 产品界面、App / 小组件展示、效率工具与数据面板、明亮通透的科技感、讲解片的「功能 / 界面」页 → 弥散玻璃（要暗夜霓虹氛围仍用赛博朋克）；
- 设计感海报、讲座 / 展览 / 活动海报、概念图解（形状、比例、对比、原则）、讲解片里的「定义 / 原理」页 → 包豪斯几何；
- 80 年代复古未来、怀旧、夏夜公路与海边、音乐和歌单封面、讲解片的「复古科技 / 回到过去」封面 → 复古 Synthwave（要雨夜城市用赛博朋克，要低分辨率游戏感用像素风）；
- 手作、DIY 教程、「从图纸到成品」的步骤图、把像素图案做成可爱实物（杯垫、挂件、冰箱贴）、讲解片里的「动手做」页 → 拼豆（要屏幕上的像素游戏感用像素风，要布上的针线用十字绣）；
- 远古、史前、起源、「人类最早的记录」、狩猎与迁徙、动物群、天文与历法、讲解片里的「历史开端 / 最早怎么记事」页 → 岩画（凿刻砂岩）；
- 古代文明、历史与考古、农业和劳动场面、「一步一步」的工序或流程讲成分栏连环画、讲解片里的「最早的记录 / 起源 / 古人怎么做」页 → 古埃及墓室壁画；
- 古典、地中海、古罗马 / 古希腊题材，海洋生物、港口与渔猎、动物图鉴，门槛或地面铭文，讲解片里的「历史 / 起源 / 古代」页 → 罗马马赛克（要屏幕上的像素格子感用像素风，要熔珠小管的手作感用拼豆）；
- 教堂、中世纪、哥特、庄严而温暖的透光，节日与季节，「一年四季 / 时间流转」的分格叙事，讲解片里的「历史 / 传统工艺」页 → 彩色玻璃花窗（要现代霓虹发光用赛博朋克）；
- 中世纪、古籍、典藏感、「古老的学问」（天文、历法、草药、炼金这类老知识）的图解、书名页和章节首页、讲解片里的「历史 / 起源」页 → 泥金手抄本（一页里要有字：正文、红字标题和首字母是它的主体）；
- 发明、机械原理、「这东西是怎么动的」、从自然到设计（仿生）、工程手稿感的讲解页、「草图 / 构思 / 研究笔记」页、复古科学插图 → 达·芬奇手稿（要现代实验记录用实验笔记本，要讲课推导用黑板板书）；
- 人物小传、宠物、家族与纪念、复古肖像、「这个人 / 这只猫 / 这条船是谁」的介绍页、怀旧礼物卡片，不能用真人照片时 → 剪影（要童趣的彩纸故事用剪纸拼贴；要老照片拼贴感用报刊拼贴）；
- 活动 / 演出 / 开业 / 讲座的复古海报、「XX 来了」式的宣告、节目单与价目、旧时代广告、19 世纪美式或民国风的印刷品、讲解片里的「历史 / 老派做法」页 → 凸版印刷海报（要几何构成的现代海报用包豪斯几何，要剪报拼贴用报刊拼贴）；
- 工业、技术、发明史，「从 A 传到 B」的原理图解（广播、电报、铁路、流水线），强对角线的海报和杂志封面，讲解片里的「年代 / 历史 / 先驱」页，需要老照片质感又不能用真人照片 → 苏联构成主义（不写政治口号；要三原色几何讲座海报用包豪斯几何，要剪报和勒索信字用报刊拼贴）；
- 旅行、交通、城市主题海报，复古而有高级感的主视觉（开业、晚会、发布会、酒店、邮轮、列车），「速度 / 现代 / 黄金年代」主题，讲解片里「历史上的未来 / 1930 年代」的封面 → 装饰艺术（要 80 年代霓虹复古用复古 Synthwave，要几何构成和三原色用包豪斯几何）；
- 复古漫画、冒险故事的「出发 / 登场 / 大事件」、怀旧玩具与少儿读物感、讲解片的「故事开场 / 角色介绍」封面、需要对白框和拟声字的画面 → 黄金时代漫画（要现代日漫用日本动漫，要拟人小物件的轻松图解用卡通手绘，要红黑两色木刻海报用凸版印刷海报）；
- 同一个东西的几种状态、情绪、版本或配色并排对比，系列头像（宠物、角色、吉祥物），「一图多版」的潮流海报，讲解片里的「同一个东西的几副面孔 / 变体对比」页，要有名人肖像的波普感又不能用真人 → 波普丝网（要单张几何海报的套色印刷用包豪斯几何；要剪报和网点老照片用报刊拼贴）；
- 计算机史、老机房、复古科技、数据和日志、「当年的电脑怎么画画」、程序员 / 极客向的配图、讲解片里的「输出结果 / 运行日志 / 打印报告」页 → ASCII 字符画（行式打印机）（要屏幕上的低分辨率游戏感用像素风，要手写板书用黑板板书）；
- 游戏感、复古 3D、「90 年代末 / 千禧年」怀旧、飞行 / 赛车 / 闯关、带 HUD 的「关卡 / 进度 / 任务」页、讲解片里的「早期 3D 图形是怎么画出来的」（线框 → 平面着色 → 贴图 → 雾）→ 低多边形（要 2D 小尺寸游戏感用像素风，要柔和现代的 3D 渲染用柔光 3D，要正交微缩模型用等轴 2.5D）；
- 街头、城市、态度与幽默、一句短口号配一个小人物的海报、公益与社区宣传、「一个人 + 一件小事」的极简故事、讲解片的「观点 / 金句」页 → 喷漆模板涂鸦（要霓虹夜景用赛博朋克；要设计感的丝网海报用包豪斯几何；要剪报拼贴用报刊拼贴）；
- 徽章、勋章、打卡 / 成就 / 里程碑、旅行与户外、社团与活动标志、讲解片里的「收集 / 解锁 / 第 N 关」页 → 刺绣徽章（要手作布艺的十字格子感用十字绣；要贴纸质感用贴纸拼贴）。

每种画风一幅范例作为质量基准（范例都不用禅意主题）；水墨另加一幅「月印万川」（留白托月、水面倒影）。

## 一、流程（每幅画都照做）

1. **定构图**，动笔前先想清楚这几项：
   - 层次：远 → 中 → 主体 → 前景；
   - 视觉焦点在哪里；
   - 留白够不够：水墨至少四成，水彩和剪纸也要有呼吸感；
   - 点睛色只用一两处：水墨用朱红，剪纸用一个亮色主角；
   - 题字或纸条放在哪里。
   - **画面要图解内容本身**，而不是随便一幅风景。
2. **写场景脚本**：复制最接近的范例改写。
3. **渲染并自己看图**：`python3 scene.py out.png`。
   - 用 Read 打开 PNG，对照第三节该画风的毛病清单逐条自查；
   - 一般改 2–4 轮，每轮只改最显眼的问题，旧版存成 `_v1/_v2` 以便对比。
4. **交付**：转成 JPG（quality 92），用当前对话渠道支持的方式发图。
   - 要做动画时加 `--stages DIR`，按 `stage('名字')` 输出各阶段快照。

## 二、接口速查

```python
import sys; sys.path.insert(0, "<本skill>/lib")
from core import spline, curve, blob_pts, fbm1d, blur, polygon_mask
```

**水墨 `Painting`**：
- `paper()`、`ridge(base, peaks=[(x,h,w)])`、`peak(SX, SY, shoulders=...)`
- `wash(ridge, dens, decay, tex, edge, mist_y)`：墨染山体，上浓下淡、带水痕边，会遮挡后面的层
- `cun()` 皴擦、`moss()` 苔点、`ridge_line()` 淡山脊线、`trails(ridge, summit, red_index)` 汇顶小路、`mist(y, h)` 雾带
- 毛笔 `stroke(pts, width, ink, dry, taper, red)`
- 物件：`pine()`、`rock()`、`sun()`、`birds()`、`pagoda()`、`traveller()`、`dot()`
- 题字印章：`title_vertical()`、`seal()`

**水彩 `Watercolor`**：
- `paper()`：冷压水彩纸纹理
- 遮罩：`shape(pts, soft, ragged)`，soft 取 1–4 是清晰的水痕边，15–40 是湿画晕开；`band(pts, width)` 是粗笔带状遮罩
- `glaze(mask, 颜色, strength, edge, gran, bloom, variation)`：透明罩染，叠加会像真颜料一样变深、混色
- `gradient_wash(y0, y1, top, bottom)`：湿画渐变天空
- 笔触：`stroke()` 彩色干笔、`line()` 细线勾勒、`lift(mask)` 提白、`splatter()` 甩点
- `soften(mask)` 任意遮罩水彩化边缘；`blobs([(cx, cy, rx, ry)])` 一组团块合成一片（树冠、灌木、云）；`mirror(mask, 水线y)` 水面倒影（带波纹断续）
- `Watercolor.petal_pts(x, y, 角度, 长, 宽)`：花瓣或叶片轮廓；`hexc('#rrggbb')` 转颜色

**剪纸 `Collage`**：
- `background(颜色, texture)`
- `piece(pts 或 mask, 颜色, texture, torn, rim, shadow)`：贴一张纸。torn 是撕边程度，rim 是撕口白边，shadow 是纸片阴影；texture 可选 paper / kraft / crayon / newsprint / notebook
- 形状遮罩：`circle_mask()`、`cloud_mask()`、`Collage.star_pts()`
- 蜡笔和光：`crayon(pts, width, 颜色)` 蜡笔线、`dot()`、`glow()`
- `face(cx, cy, r, mood='smile'|'sleep'|'dots')`：笑眼、嘴、腮红
- `text(s, x, y, size, 颜色, vertical)`

**韩国彩铅 `ColorPencil`**：
- `paper()`：细纸纹
- 遮罩：`mask_poly(pts)`、`mask_blob()`、`mask_ellipse()`
- `hatch(mask, 颜色, pressure, angle)`：短排线铺色。蜡只挂在纸纹凸起上，pressure 越大越能压进凹处；边缘自动变淡
- `shade(mask, 颜色, angle=另一个角度)`：交叉排线加阴影
- `outline(pts, '#8a6a5a')`：浅褐色铅笔勾线；`line(pts)` 用于不闭合的线
- `sparkle(x, y, r)` 白色高光笔；`dots(mask, 颜色)` 草莓籽、糖粒之类
- 白色物体不要用白色画（白纸上看不见）：用暖奶白色，配淡紫灰或淡蓝灰阴影

**日本动漫 `Anime`**：
- `sky(top, mid, horizon_col, horizon)`：天空渐变
- `cumulus(cx, base_y, w, h, light)`：积雨云。许多不规则团块从后往前叠，每团的暗面是「团块减去朝光源偏移的自身」形成的月牙形硬边
- `sun_flare(x, y)`：光晕、光束、镜头光斑；`sparkles()`；最后加 `bloom()` 泛光和 `vignette()` 暗角
- `field(top_y, colours)`：平涂分带的田野；`pole()` 电线杆、`wire(p0, p1, sag)` 下垂电线
- 平涂和线稿：`fill(mask, 颜色)`、`gradient()`、`screen()`；`lines(pts, width, 颜色)` 画干净线稿；`poly()`、`circle()`
- 角色：平涂两色（亮色和阴影色）加深色描边

**编辑风手绘 `Editorial`**：
- 形状：`circle()`、`ellipse()`、`rrect()` 圆角矩形、`blob()`、`poly()`
- `fill(mask, 专色)`：印一层专色油墨，带颗粒、浓淡不匀、套色错位，并**叠印**（重叠处颜色相乘）
- `halftone(mask, 专色, cell, angle, amount)`：半调网点做明暗
- `line(pts, 墨色, width, wobble, breaks)`：歪扭的手绘墨线；`dashes()` 虚线；`stars()` 小十字星
- 专色控制在 4–5 种，并刻意让它们互相重叠，叠出第三种颜色

**油画厚涂 `OilPainting`**：
- 先准备两张图：参考色 `ref`（H×W×3，画面要画成什么颜色）和流向图 `ang`（H×W，每个像素上笔触的角度，比如天空打旋、麦田横扫、树木向上）
- `layer(ref, ang, length, width, density, mask)`：铺一层笔触。先大笔铺底，再中笔，最后只在要紧处（`mask`）加细节笔
- `stroke_at(x, y, angle, length, width, 颜色)`：在指定位置画一笔（乌鸦、签名、点睛）
- `render()` 自动打光：颜料平顶鼓边、有笔毛沟，落笔处更厚

**浮世绘 `Ukiyoe`**：
- `block(mask, 颜色)`：印一块平涂色版，带木纹和套印偏移
- `bokashi(mask, 颜色, y_strong, y_fade)`：晕色，从某一边浓到另一边消失，用于天空和海面
- `key(pts, width)`：墨色主版勾线
- 物件：`cloud_band(x0, x1, y, h, glow)` 不透明云带、`seigaiha(mask, 颜色, r)` 青海波纹
- 标题签和朱印：`cartouche(x, y, w, h, '标题')`、`seal()`
- 形状：`poly()`、`rect()`、`circle()`

**像素风 `PixelArt`**：
- 在低分辨率上画（默认 320×180，放大 6 倍）。坐标都是整数像素
- 画形状：`rect()`、`poly()`、`circle()`、`line()`（Bresenham 直线）、`outline(mask)`、`put(x, y)`
- 抖动：`gradient(x0, y0, x1, y1, c0, c1, steps)` 分带渐变，带与带之间用抖动过渡；`dither(mask, 颜色, alpha)` 按 Bayer 矩阵抖动上色；`glow(cx, cy, r, 颜色)` 抖动光晕
- 其他：`text('CAFE', x, y, 颜色, size)` 3×5 像素字、`rain()` 雨丝
- 交付用 PNG（无损），像素才清晰

**黏土定格 `Clay`**：
- 同时维护高度图（像素为单位）和颜色图，最后用影棚光一次性打光。部件默认「铺」在下面的东西上（`base=None`），先远后近、后铺的在上
- `backdrop(颜色)` 底板；`gradient(top, bottom, y0, y1)` 生成颜色场，可传给 `pad`/`smear`
- 部件：`pad(mask, 颜色, height, round)` 压平的一片（round 小是硬边薄片，大是鼓鼓的枕头形）、`ball(x, y, r)` 小球、`snake(pts, r, taper=(起, 止))` 搓条（线条、浪花、嘴、茎）、`text(s, x, y, size)` 鼓起的黏土字
- 工具痕：`groove(pts, width, depth)` 刻线、`poke(x, y, r, depth)` 戳洞；`smear(mask, 颜色场)` 手指抹开的一大片（会把相邻颜色拖混，留下柔和的指痕脊）
- `marble=('#颜色', 0.25)` 两色没揉匀的纹路；表面自动带小疙瘩和指纹
- 遮罩：`circle()`、`ellipse()`、`poly()`、`blob()`、`rrect()`

**蓝晒 `Cyanotype`**：
- 思路是「挡紫外线」而不是「上颜料」：放上去的东西按不透明度挡光，透过率相乘；最后显影成普鲁士蓝
- `coat(x0, y0, x1, y1)` 刷涂药水：一笔笔横刷，笔尾是干刷的断续刷丝，边上会甩几滴药水
- `place(mask, opacity, lift, texture)`：opacity 薄叶约 0.85、叶脉 1.0、绒毛约 0.3；lift 是离纸的高度（0 压平清晰，1–3 柔和半影）；texture 是叶肉的不均匀
- 批量画遮罩：`shapes([轮廓...])` 一次画很多片叶子，`lines([折线...], width, taper)` 一次画很多茎、叶脉、绒毛；`Cyanotype.leaf_pts(x, y, 角度, 长, 宽, tip, blunt)` 叶片轮廓
- 文字：`label()` 白色手写字（写在透明片上一起晒）、`pencil()` 晒完后写在纸边的铅笔字

**十字绣 `Stitch`**：
- 一切都在布孔的格子上（`cell` 像素一格）。`cells(mask)` 把像素遮罩变成格子，`at(gx, gy)` 取格子中心
- 针法：`cross(格子, 颜色)` 十字绣、`half(格子, 颜色)` 半针（天空、云、烟）、`back(pts, 颜色, step)` 回针（路径吸附到孔上，一针约 step 格）、`running(pts)` 平针虚线、`satin(mask, 颜色, angle)` 缎面绣（鼓起、有光泽）、`satin_text(s, x, y, size)`、`knot(x, y, 颜色)` 法式结
- 图样：`chart(['..#..', '.###.'], gx, gy, {'#': 颜色})` 按字符图绣；`letters('HOME', gx, gy, 颜色, scale)` 5×7 字母
- `label(x0, y0, x1, y1, 'EST. 2026')` 缝上去的织标

**复古仪器面板 `Panel`**：
- 所有部件都由同一盏左上方的主光照亮：朝光的边亮、背光的边暗、凸起的部件向右下投影
- 材质：`surface(mask, 材质, 颜色, height)`，材质可选 wood（柚木）、brushed（拉丝铝）、plastic、painted、fabric（喇叭布，`lurex=` 金丝）；`recess(mask, 材质, 颜色, depth)` 下凹的窗口；`background()`、`paint()`、`glow()`、`drop_shadow()`
- 控件：`knob(x, y, r, angle)` 车削旋钮、`button()` 琴键（`pressed=True` 按下）、`toggle()` 拨杆开关、`lamp()` 宝石指示灯、`magic_eye()` 绿色魔眼调谐管、`meter()` 指针表、`screw()` 螺丝、`grille()` 冲孔网、`badge()` 镀铬草书铭牌
- 印刷：`text(s, x, y, size, spacing=)` 丝印字、`scale_arc()` 圆弧刻度、`scale_linear()` 直尺刻度、`glass(mask)` 玻璃反光

**贴纸拼贴 · 小票 `Sticker`**：
- 思路：每样东西先在自己的透明小画纸 `Art` 上画成平面矢量图，再决定材质：`stick()` 做成模切贴纸，`lay()` 当纸平放
- `board(颜色, kind='cream'|'kraft')`：奶油色或浅牛皮纸底板，带纸纹、斑驳、纤维和杂点
- `art(w, h)` 返回 `Art`：遮罩 `circle/ring/ellipse/rrect/poly/blob/line/text`（中西文混排，`stroke` 加粗）；上色 `fill(mask, 颜色, alpha, clip)`、`gradient()`、`radial()`；`crescent(mask, dx, dy)` 明暗月牙；`speckle()` 撒面粉、籽粒；`cut()` 打孔；`texture('kraft')` 牛皮纸纹
- `stick(art, cx, cy, rot, border=14, peel='tr'|'tl'|'br'|'bl', peel_size, lift, gloss)`：模切贴纸。白边按圆角外扩，有切口厚度、覆膜高光和斜向反光，贴地阴影加柔和投影；`peel` 翻起一角，露出浅色背面和它自己的影子
- `lay(art, cx, cy, rot, curl, lift)`：纸张平放（小票、吊牌），两端微翘、翘起处影子更长；返回局部→画面坐标映射 `T(x, y)`，用来在纸上落笔、盖章
- `receipt(w, h)` 返回 `Receipt`：锯齿撕边、热敏灰字（断针竖纹、走纸浓淡、小掉点）；`centre()` 居中打印、`row(y, 名称, 金额, was='旧价')` 带点线引导和删除线、`rule('dash'|'stars'|'double')`、`barcode()`、`crease(y)` 折痕
- `tape(cx, cy, 长, rot, 颜色, pattern='stripe'|'dot'|'grid'|'plain')` 半透明和纸胶带，两头手撕锯齿；`tag_art(w, h, 颜色, 金属扣颜色)` 吊牌（`.hole` 是孔位），`twine(点列)` 双色面包师麻绳
- `stamp(cx, cy, r, 环形字, 中心字, 小字, 颜色, rot)` 圆形橡皮章（油墨半透明、压力不匀、字边积墨、漏印小坑）；`pen(点列, 颜色, width)` 红色圆珠笔（打勾、圈总价、划掉）
- 现成贴纸：`lettering_art([(文字, 颜色), ...], size)` 大字、`label_art()` 胶囊标签、`badge_art(r, 颜色, '-20%', top, bottom)` 波浪边促销贴

**实验笔记本 · 贴纸 `Notebook`**：
- 场景：`desk()` 石墨蓝灰桌面；`notebook(x0, y0, x1, y1, tabs, stack, ear, margin, header, grid, major)` 一整本笔记本（硬封底、分隔标签、错开的页边、青色方格纸、红色双边线、打孔、折角）；`binding()` 线圈（按金属管打光，带投影）
- 铅笔：`pencil(pts, width, pressure, jitter)` 手绘一笔（样条平滑、手抖、起笔轻收笔提）；`pencils([...])`；`rule(x0, y0, x1, y1)` 靠尺直线；`hatch(mask, angle, spacing, pressure)` 排线；`checkbox(x, y, size, checked)`；`arrowhead(tip, 方向)`；`axes(x0, y0, x1, y1, xlim, ylim, xticks, yticks, xlabels, ylabels)` 返回 `to_px(x, y)`
- 石墨只挂在纸纹凸起上：pressure 小是颗粒状浅灰，大才填满；线宽约 2–3.5 px
- 荧光笔 `highlight(x0, x1, y, h, tilt, alpha)`：正片叠底，斜切起笔并积墨、边缘毛、纵向纤维条纹、尾部断续，两遍重叠处更深
- 红笔：`pen(pts, width)`、`pen_loop(cx, cy, rx, ry, rot, turns=1.12)` 不闭合的圈、`pen_arrow(pts, head)`、`pen_underline(x0, x1, y, double)`
- 文字 `text(s, x, y, size, colour, font, anchor, rot, spacing, weight, medium)`：font 用 sans / sans_bold / typewriter / cjk_sans（中英混排自动换字体），medium 可选 ink、print、typed（打字机，每字浓淡和基线略不同）、pencil、opaque；`text_width()` 量宽度
- 纸片：`sticky(cx, cy, w, h, rot, colour)` 便利贴（上端平贴、下端翘起投影），返回 Frame，用 `f.pt(lx, ly)` 和 `rot=f.rot` 往上写字；`sticker(cx, cy, w, h, rot, colour, shape='rrect'|'circle', lines=[...])` 模切贴纸；`label_tape(s, x, y, size, rot)` 标签机胶带；`stain(cx, cy, r)` 咖啡杯印
- 道具：`pencil_prop(x, y, angle, length, width, label, end='eraser'|'plain')` 六棱铅笔
- 角度：`rot` 逆时针为正（同 PIL）；`angle`（铅笔、箭头方向）是屏幕角度，顺时针为正。常用色：`INK SOFT LEAD RED HI MINT MINTD`

**黑板板书 `Chalkboard`**：
- 分层：石板漆 → 粉笔层（预乘颜色 + 透明度，板擦能擦掉）→ 板前物件（木框、粉笔槽、粉笔、板擦及其投影）→ 室内光与暗角
- 板面：`slate()` 云状不匀的墨绿石板漆；`dust(amount, specks, haze)` 沉降的粉笔灰，越往下越厚；`frame(rail, top, ledge)` 斜接木框加粉笔槽，会设置写字区 `area` 和槽面高度 `tray_y`。默认尺寸构造时就已知，dust 和擦痕可以先于画框画
- 板擦：`swipe(pts, width, strength, haze, smear, keep)` 沿路径擦一遍：带走粉笔、顺擦向拖出残迹、毡面梳出细纹、毡面两端积灰；`smudge(cx, cy, w, h, rot)` 短擦一下；`with cb.erased(keep, angle, smear):` 块里画的一切都变成擦过没洗的旧课残影
- 笔尖：`stroke(pts, colour, width, pressure, jitter)` / `strokes([...])`；`line()` 徒手直线、`rule()` 靠尺直线；`box(x0, y0, x1, y1, gap=(xa, xb))` 四边出头，上边可留缺口写标签；`loop(cx, cy, rx, ry, rot, turns)` 不闭合的圈、`circle()`；`arrow(pts, head)` 两笔箭头在尖端叠厚；`underline(x0, x1, y, double)`；`wave(p0, p1, wavelength, amplitude)` 光波曲线带箭头；`dashed()` 一段段画的虚线；`dot()`；`hatch(mask, angle, spacing)` 排线；`propto(x, y, size)` 手写 ∝，返回宽度
- 侧锋：`side(p0, p1, stick, pressure)` 粉笔横躺拖一笔；`shade(mask, colour, angle, stick, pressure, overlap, weight)` 侧锋铺色，weight 是全画布 0–1 的压力图，可做渐变
- 粉笔只挂在板面「齿」的凸起上：pressure 0.2–0.4 颗粒稀疏（铺色），0.8–0.95 写字画线
- 文字 `text(s, x, y, size, colour, font, anchor, pressure, weight, rot, spacing, hand, grain)`：font 用 sans / sans_bold / cjk_sans，某套字体缺字自动换另一套；每个字各自微转、错位、轻重不一（hand=0 为排版体）；`text_width()` 量宽度
- 道具：`chalk_stick(x, cb.tray_y, length, colour, rot, worn='right'|'left'|None)` 粉笔，一端磨斜；`eraser(x, cb.tray_y + 2)` 板擦；`crumbs(x0, x1, n)` 碎粉笔
- 颜色：`WHITE YELLOW PINK BLUE` 为主，`RED ORANGE GREEN VIOLET` 用于光谱和彩色粉笔，另有 `DUST`；所有 angle 和 rot 都是逆时针为正

**赛博朋克 `Cyberpunk`**：
- 思路：一台水平的针孔相机看向街道深处，世界坐标 X 右、Y 上、Z 向前，单位是米。所有东西写进 HDR 缓冲（反照率、自发光、z-buffer 深度、倒影镜像行），调用顺序不影响遮挡；`render` 时统一算光：环境光 + 光源外溢照明、深度雾（雾色是城市光的散射）、地面倒影、蒸汽、雨、胶片
- 构造：`Cyberpunk(W, H, seed, focal=1150, vp=(x, y), eye=1.7, fog=125, wall=9.5, road=6, record=True)`；`record=False` 时 `stage()` 不出快照，渲染更快。相机工具：`project(X, Y, Z)`、`ground_row(Z)`、`near_z(side)`
- 远景：`sky()` 被街灯从下面照亮的低云；`skyline(z, x_range, heights, widths)` 远处塔楼剪影、针点窗光、红色航空灯；`light(x, y, r, 颜色, z)` 小点光源
- 楼：`building(side, z0, z1, height, wall, colour, lit, shops=(亮店, 卷帘门, 暗店, 自动售货机))` 透视楼块，正面加沿街立面贴图（窗格、空调外机、雨痕、底商、招牌字，右侧立面的字会自动镜像）
- 霓虹：`blade_sign(side, z, Y0, Y1, '字', 颜色, reach, border=颜色, latin='BAR', dead=[序号], flicker=[序号], kind='neon'|'box', text_colour, level)` 伸向街心、面向镜头的竖招牌；`sign(z, X0, X1, Y0, Y1, ..., vertical=False)` 横招牌或立式灯箱；`neon_text(s, x, y, size, 颜色, z, vertical, dead, flicker)`、`neon_path(点列, 颜色, z)` 任意灯管
- 全息：`hologram(z, X0, X1, Y0, Y1, '海月', 'SEA MOON', level, jelly=(x, y), sub_y)` 半透明投影广告（海月水母、竖排明朝标题、扫描线、撕裂切片、色边、投影边框），只加光，还会照亮雾和墙
- 街道：`street(crossing=(z, 宽), puddles)` 湿沥青、路缘、铺砖、斑马线、积水；`puddle(X, Z, rx, rz)` 指定水洼（放在近处招牌的倒影位置上，能倒映出整块招牌）；`grate(X, Z)` 井盖格栅
- 空中：`walkway(z, Y, thick, deep, windows=None)` 过街天桥（正面可再挂 `neon_text`）；`cables(n, z=(近, 远), Y=(低, 高))` 电线；`light_trail(三维控制点, 颜色, pair, strobe, fade)` 飞车光轨（左行交通：尾灯红、头灯暖白）
- 氛围：`steam(X, Z, height, width, drift, density)` 井盖蒸汽；`mist()` 只躺在远处街面的薄雾；`figure(X, Z, umbrella='clear'|'dark'|None)` 打伞背影（两侧霓虹轮廓光，无脸）；`rain(far, mid, near, slant, rings)` 三层雨和溅落圈；`glitch(y, h, shift, split)` 一道撕裂扫描线，只在成片里出现，用一次就够
- 颜色常量 `MAGENTA CYAN AMBER RED WHITE`；`save('x.jpg')` 默认 quality 88、4:4:4 色度，霓虹边缘不糊

**卡通手绘 `Cartoon`**：
- 思路：照动画师画一张原画的顺序——蓝铅笔起稿 → 勾线 → 平涂 → 赛璐璐阴影 → 蜡笔/网点 → 特效 → 字。每一笔按种类落进一个「组」：`rough` 铅笔、`ink` 墨线、`flat` 平涂、`shade` 阴影/高光/腮红、`texture` 蜡笔/网点/排线、`fx` 特效、`type` 字。`stage(name, show=[组...], rough=强度)` 只显示这些组，画完的一张图可以按作画顺序回放；`with c.group(ink='ink_bg'):` 把某一类改投到别的组，`with c.group('fx'):` 全部改投
- 遮挡：东西不透明，`fill` 会挖掉身后已画的墨线和颜色（隐藏线自动去掉），所以先远后近；`fx`、`type` 是最后叠上去的覆盖层，它们的挖空只在显示时生效，阶段快照不会出现空洞
- 墨线：`line(pts, width, taper)` 毛笔线（落笔细、中段粗、收笔尖，有手抖和压力起伏）；`outline(pts, width, weight, gaps)` 一笔画完的闭合轮廓，首尾两个尖头交叠，背光的右下侧按 weight 加粗，`gaps=n` 留几处小断口；`ink_fill()` 实心墨块、`dot()` 墨点。每条墨线会自动先起一遍蓝铅笔稿（`rough=False` 关掉），`sketch()` 只画铅笔辅助线
- 颜色：`fill(pts|mask, 颜色, slop)` 平涂，整体错开 slop 像素、边缘游走，返回 `Mask`，可作 clip；`shade(形状, 颜色, offset=(dx, dy), clip)` 硬边赛璐璐阴影（形状减去朝光源挪过的自己，得到背光侧的月牙），offset=None 时直接用给的形状；`glint(pts, width)` 白色高光笔；`shape(pts, 颜色, shade=(颜色, dx, dy), shade2=...)` 一次做完平涂、两层阴影和描边；`darker(颜色)` 取阴影色
- 质感：`crayon(形状, 颜色, pressure, angle)` 蜡笔（只挂在纸纹凸起上，顺着涂的方向有条纹，毛边；pressure 可以是整幅数组，做渐变）；`tone(形状, 颜色, cell, angle, amount)` 网点纸；`hatch(形状, angle, spacing)` 墨线排线（接触阴影）；`blush()` 腮红
- 角色：`face(cx, cy, size, mood, rot)`，mood 可选 happy（^ ^ 眼加张嘴吐舌）、wow（圆眼加 o 嘴）、sleepy、smile、wink，自带腮红；`arm(肩, 手, bend, hand, thumb)` 橡皮管手臂加带拇指的白手套（先画手臂再画身体）
- 特效（默认进 fx 覆盖层，`fx=False` 当普通物件画）：`sparkle()` 四角闪光星、`speed_lines(p0, p1, angle)` 速度线、`steam()` 热气、`puff()` 扇贝边烟团、`burst()` 爆炸星形框、`crumbs(..., avoid=遮罩)` 飞溅碎屑、`pop_lines()` 强调短线
- 字（默认进 type 覆盖层）：`letter(s, x, y, size, fill, depth, depth_colour)` 大标题字（中文圆体加漫画西文，每个字微转、上下跳，带挤出阴影、左上白边和粗墨描边）；`note()` 手写注释；`arrow()` 手绘箭头；`badge(x, y, r, '1')` 编号圆标；`pencil_note()` 纸角的蓝铅笔编号；`text_width()` 量宽度
- 形状：`Cartoon.rrect_pts(x0, y0, x1, y1, r 或 (左上, 右上, 右下, 左下))`、`ellipse_pts(cx, cy, rx, ry, rot, a0, a1)`（给 a0/a1 就是一段弧）、`densify()` 保留尖角的折线、`place(局部点, cx, cy, scale, rot)` 摆放在局部坐标里画好的物件；`mask(pts)` 整幅遮罩，可以用 numpy 相乘相减
- 抖线：`Cartoon(..., boil=2.0)`，每次 `stage()` 用一张新的平滑位移场重描墨线（1–2 像素），颜色和铅笔稿不动；`save()` 用第 0 次描线
- 角度都是逆时针为正（同 PIL）；颜色常量 `INK PAPER PENCIL WHITE RED YELLOW PINK ORANGE`

**等轴 2.5D `Isometric`**：
- 思路：一台正等轴正交相机加一个小光线追踪器。每个部件都是解析实体（平面围成的凸多面体、任意轴向的圆台、可被平面切开的椭球），逐像素求交写进 G-buffer（深度、法线、反照率、材质），画的先后不影响遮挡。同样的实体再从太阳方向画一张阴影图、从正上方画一张记录「柱子顶和底」的高度图，最后统一算光：天空环境光 × AO + 太阳 × N·L × 软阴影（PCSS，半影随遮挡距离变宽）
- 构造：`Isometric(W, H, seed, scale=每格像素, look=(x, y, z), at=(屏幕比例 x, y), sun=(x, y, z), ss=2, floor=-2.4, record=True)`。世界 x 朝屏幕左下、y 朝右下、z 朝上，一格 = 1。`iso(x, y, z)` 世界 → 屏幕；`unproject(sx, sy, z)` 屏幕 → 该高度平面上的世界点（按屏幕位置摆悬浮物）
- 地面：`backdrop(top, bottom, glow, centre)` 浅色渐变和底座下面看不见的地板（接住底座的影子）；`slab(x0, y0, x1, y1, z0, z1, layers)` 漂浮的分层底座；`tiles(levels, heights, colours, soil, gap, paved=(4,))` 倒角地砖（0 海、1 沙、2 草、3 台地、4 铺装）；`sea(shallow, deep, foam, waves)` 海面（岸边浪花、断续第二道浪线、深浅过渡、浪短线、透亮侧壁）；`top_z(x, y)` 取砖面高度；`road()` 带中心虚线的路；`path(cells)` 石板
- 基本体：`box(x0, y0, z0, x1, y1, z1, colour, side, bevel)` 倒角盒子；`obox(centre, size, yaw, pitch, roll)`；`prism(pts, z0, z1)`；`convex([(normal, d)], lo, hi)`；`cylinder(x, y, z0, z1, r, r1=None)`（给 r1 是圆锥 / 圆台）；`tube(p0, p1, r)`；`ellipsoid(centre, radii, yaw, pitch, roll, clip=[(normal, d)])`、`sphere()`、`dome()`。都接受 `paint(P, n, tag)`（按世界坐标上色：砖缝、土层、瓦行、百叶、电池片、卡面文字）、`mat='matte'|'water'|'glass'|'soft'|'gloss'|'card'`、`cast=`（投不投影）、`ao=`（进不进高度图：悬浮物和细线都关掉）
- 建筑：`building(x0, y0, x1, y1, z, h, wall, roof='gable'|'hip'|'shed'|'flat', roof_colour, axis, windows=(行, +x 墙几扇, +y 墙几扇), door=('+x', 位置), trim)`；`roof()`；`window(x, y, z, w, h, facing)`（白框、十字棂、斜向天光、窗台）；`door()`；`sign(x, y, z, w, h, '字', facing)`
- 自然与道具：`tree(x, y, z, size, kind='round'|'pine'|'poplar'|'bush', flowers=)`、`rock()`、`cloud()` 平底云、`windmill(x, y, z, h, yaw, spin)`、`windsock()`、`dish()` 卫星天线、`solar_panel()`、`fence(pts, z, h, closed)`、`pier()`、`boat()`、`balloon()`
- 信息图：`card(x, y, z, w, h, facing='+x', title, tag, value, unit, note, series, icon='wind'|'temp'|'rain'|'balloon'|'sun', anchor=(x, y, z), accent)` 竖在空中的数据卡（文字印在等轴平面上，带细引线和锚点）；`compass(x, y, z, r, north)` 平躺在地面上的指北针；`text()`、`rule()`、`dot()` 平面排版叠在最上层
- 光：太阳从左后上方来，顶面最亮，+x 面（左下）次之，+y 面（右下）只吃天光；`sun_c / sky_c / hor_c / gnd_c`、`soft`、`pen`（最小 / 最大半影）可调。不要霓虹发光、泛光和描边

**单线画 `LineArt`**：
- 思路：整幅画是一条路径。先把各个形状做成点列，再 `chain()` 按作画顺序串成一条线；线只栅格化一次成「时间图」（每个子像素记住笔第一次经过时走了多少像素），画到哪一步就是 `时间 <= s`
- 底：`backdrop('night'|'cream')`：深蓝丝绒底（中间亮、细颗粒）或奶油纸，同时设定默认线色（金 / 墨）和点睛色（琥珀 / 朱红）
- 形状（静态方法，返回点列）：`smooth(控制点)` 样条、`poly(点, r, sharp=(下标,))` 圆角折线、`arc(cx, cy, rx, ry, a0, a1)`、`scallop(cx, cy, r, a0, a1, bumps, depth)` 树冠灌木的扇贝边、`place(点, 原点, angle, scale)` 局部坐标摆放、`curl(P, s, r, span, side, aspect)` 在路径第 s 像素处插一个翻圈、`retrace(点)` 原路去再原路回
- 路径：`chain([(名字, 点列), ...])` 返回 `(P, marks)`，断开处自动用切线连续的三次曲线接上；`trim(P, s0, s1)` 按长度裁剪；`locate(P, (x, y))` 最近点的长度；`at(P, s)` 取点和方向；`length(P)`
- 画线：`line(P, width, pressure=[(s0, s1, 倍数)], sheen, glow, hot)`：起笔轻、收笔长尖、压力缓慢起伏、急转处变粗、原路折返处提笔收尖；深色底上是随角度变亮、只带一点柔光的金线
- 动画：`draw_to(s 或 marks 名字)` 移动笔头，没画完时笔头带光点、刚画的一段更亮；`stage(name)`
- 点睛：`accent(遮罩, 颜色, glow, warm)`，遮罩用 `rect()`、`disc()`；深色底上会发光，并把附近的线染暖
- 文字：`text(s, x, y, size, colour, font='display', spacing)`（Didot 类衬线，中文自动换细宋体）、`text_width()`、`hairline()` 细装饰线
- 颜色常量 `GOLD GOLD_HI GOLD_LO AMBER VERMILION NIGHT CREAM INK`；`save('x.jpg')` 默认 quality 88、4:4:4

**柔光 3D `Soft3D`**：
- 真 3D：`Soft3D(W, H, seed, eye, target, fov)` 针孔相机，世界坐标 X 右、Y 上、Z 远离镜头；每个像素一条光线，numpy 在 CPU 上算
- 球海 `ball_field(x0, x1, z0, z1, r, gap, colours, weights, mat)`：方格上成千上万颗球，光线逐格查找（DDA），每格只测一颗球，十万颗也不慢；`tint_balls(x, z, radius, colours, chance)` 局部换色；`floor(颜色)` 球缝里看到的地板
- 主体（有向距离场，只在自己的包围盒里步进）：`text(s, at, size, depth, colour, mat, yaw, spacing, bob, roll, turn, dot)` 鼓鼓的挤出字（字形→精确距离变换→挤出、整圈倒圆、再吹胀；`dot=颜色` 把 i/j 的点换成一颗球；返回 {'heroes', 'dots', 'centre'}）；`rbox()` 圆角盒、`capsule()` 胶囊、`cylinder()` 圆角圆柱、`torus()` 圆环
- `part(heap, reach, pile, pile_top)`：主体从球海里顶出来，被挤开的球落进最近的空窝、堆在脚边（pile 是被挤开球数的倍数，pile_top 是堆的最高高度，别让它挡住字的下半截），周围的球海微微隆起
- 散球：`ball(x, y, z, r, 颜色)` 指定位置；`drop(x, z, r, 颜色, roll)` 从上方落下碰到东西为止，再往低处滚进窝里（roll=0 停在落点，比如骑在字肩上）
- 灯光：`sky(top, horizon, strength, haze, haze_start)` 天光穹顶（背景渐变、地面反光、远处雾）；`key(azimuth, elevation, strength, size)` 大柔光箱主光，size 越大影子越软；`rim()` 轮廓光；`softbox()` 只出现在反光里的灯片。方位角从镜头算：0 从相机身后，−90 左，+90 右，180 主体背后
- 材质 `mat=`：candy（清漆糖果，锐利灯片高光）、satin（缎面小球）、jelly、matte、pearl；缝隙和阴影变深变饱和而不发灰
- `lens(focus, aperture)` 景深（focus 可传 text() 的返回值或一个点，最好和相机一起先设）；`film(bloom, vignette, grain)`
- `save(path, stages_dir, ss=1.5)` 成片超采样；`stage(name)` 是当前场景的真实预览渲染，还没调用 sky() 时是灰色白模

**形变动画 `Morph`**：
- 思路：每样东西都是**一条**闭合轮廓；两条轮廓重采样成同样点数（默认 `Morph.N = 256`）、统一绕向、对齐起点，再逐点插值，就是形变；背景色和形状颜色跟着切换
- 形状库 `shape(name, cx, cy, size, rot, flip, stretch)`：`SHAPES` 有 circle / square / triangle / star / heart / drop / cloud / snowflake / mountain / river / wave / sun / moon / leaf / bird / fish / pin / house；`union([('circle', x, y, r), ('line', 点列, 宽), ('poly', 点列), ('sub', 图元)], cx, cy, size)` 用图元拼出自己的形状，自动描出外轮廓
- 几何：`resample(P, n)` 按弧长等距重采样；`normalise(P)` 顺时针、从正上方起；`align(A, B)` 统一绕向并用 FFT 找最佳起点；`chain([...])` 整串依次对齐；`ease(t, 'inout'|'sine'|'quad'|'in'|'out'|'back'|'expo'|'linear')`；`tween(A, B, s, at=, stretch=, direction=, spin=, scale=)` 轮廓绕质心插值、质心单独走运动路径，stretch 是沿运动方向的挤压拉伸；`at(keys, T)` 整串关键帧在全局时间 T 的轮廓（逐帧做真动画用）；`mix(c0, c1, t)` 在 OKLab 里混色（蓝到黄不发灰）
- 背景：`paper(颜色)`；`panel(x0, y0, x1, y1, 颜色, ink=)` 一块纯色面板，ink 是画在这块面板上的残影和线条默认用的颜色；`wipe(cx, cy, r, 颜色, ink, clip_box)` 定格的圆形转场
- 形状层：`fill(P, 颜色, alpha, clip=另一轮廓, half=((x0, y0), (x1, y1)))`，half 只填直线右侧，用来做两色折面；`outline(P, 颜色, width, dash=(实, 虚))`；`stroke(点列, 颜色, width)` 圆头线（高光、水纹、热气）；`dot()`
- 定格动画：`ghost(P, fill, fill_alpha, line_alpha, width)` 洋葱皮残影，线色为 None 时取下面面板的 ink，跨面板自动换色；`points(P, every)` 标出对应点；`links(A, B, every)` 对应点连线；`path(点列)` 过质心的平滑路径，`along(路径, u)` 取点和方向；`trail(路径, dash=)` 运动轨迹；`chevron()` 方向箭头；`streaks()` 速度线
- 时间轴：`diamond(x, y, r, fill)` 关键帧菱形；`ease_curve(x0, y0, x1, y1, kind, ticks=帧时间)` 一段缓动曲线，带帧点和虚线投影
- 文字 `text(s, x, y, size, 颜色, font='sans'|'display'|'mono'|'mono_bold'|'cjk'|'cjk_bold', anchor='l'|'m'|'r', spacing, alpha)`：y 是基线，中西文自动换字体，返回宽度；`text_width()` 量宽度
- 坐标都是像素、y 向下；角度逆时针为正

**报刊拼贴 `NewsCollage`**：
- 思路：每样东西都是「先印好、再撕或剪、最后粘上去」的一张纸 `Sheet`；老照片不是贴图，而是 `Photo` 用高度图布光渲染出来，再印成网点
- 底板：`board()` 牛皮纸（云状纸浆、深浅短纤维、树皮碎屑）
- 纸片：`sheet(w, h, 颜色)` 返回 `Sheet`，可用 `text()`、`block(…, minus=文字遮罩)` 反白字、`ink()`、`rule()`；`tear('rtb', depth, rim)` 手撕（边线游走、露出白色纸芯、飞出纤维），其余边算剪刀剪；`cut_rect()` 歪一点的剪刀四边形；`cut(pts)`；`wrinkle()` 浆糊起皱；`age()` 泛黄和霉斑
- 报纸：`newsprint(w, h, columns, size, headline, picture, ad)` 返回一整版假报纸（伪词栏、刊头线、大标题、导语、小标题、栏线、框线广告、网点小照片、背面透印），接着 `tear()`
- 老照片：在 `Photo(w, h)` 上搭物件：`disc()`、`dome(…, rot, cut)`（钟铃、球）、`ring()`（表圈）、`rod()`、`poly()`（指针）、`gear(r, teeth, spokes, pinion)`、`spiral(r0, r1, turns, flare)`（发条、游丝）、`screw()`；`text()` / `lines()` 印在表面的字和刻度；`glare()` 玻璃反光。z 是底座高度，height 是自身厚度，albedo / metal / gloss 是材质
- 印成网点：`print_photo(photo, cell, angle, ink)` 显影并印成网点，返回 Sheet；`s.cutout(margin, centre)` 沿轮廓用剪刀剪下；`s.split(p0, p1)` 一剪两半
- 粘贴：`paste(sheet, cx, cy, rot, lift)` 返回 Frame，`f.pt(lx, ly)` 把局部坐标换成画面坐标；`disc(cx, cy, r, 颜色)` 剪刀剪的色纸圆
- 字：`ransom('拆开看看', x, y, size, faces=[…], styles=[…])` 勒索信拼贴字，返回 [(Frame, 字)]；`clipping(字, size, face, paper, block, fg, extra)` 单个剪字，extra 可选 'text'（带邻字）或 'tint'（网点底）；`label(文字, x, y, size, face, fg, bg, block)` 剪下的一条印刷字
- 其他：`tape(cx, cy, 长, rot)` 美纹纸胶带；`stamp(cx, cy, [(字, 字号)], shape='box'|'round', ring=环形字)` 橡皮章；`pen(pts, dash=(实, 虚), dot)` 墨线引线
- 字体：news / news_bold / news_italic / serif_bold / slab / clarendon / didone / poster / futura / grotesk / typewriter(_bold) / cjk_song / cjk_hei / cjk_round / cjk_kai；缺字自动换中文黑体
- 颜色常量 `INK BLACK RED MUSTARD KRAFT NEWS PAPER TAPE`；rot 逆时针为正

**弥散玻璃 `Aurora`**：
- 思路：一块明亮的「光屏」（弥散渐变）上面悬着几片真的磨砂玻璃。透过玻璃看到的是它下面**真实像素**的高斯模糊（背景、小球、后面的卡片和字都算），再蒙一层白纱，界面印在玻璃上。先画的在后面，后画的卡片会把前面画好的卡片连字一起模糊
- 背景：`backdrop(base, blobs=[(x, y, rx, ry, 颜色, 强度)], ribbons=[(点列, 宽, 颜色, 强度)], warp, grain)` 网格渐变：色团按权重在 OKLab 里混色，坐标扭曲成不规则形状，光带沿样条走，自带细颗粒；`sparkles(n)` 零星光点；`orb(cx, cy, r, (亮, 中, 暗))` 光泽小球：虹彩色阶、菲涅尔边缘映出背景色、高光、落在背景上的彩色投影
- 玻璃：`glass(x0, y0, x1, y1, radius, blur, tint, sat, shadow, elevation, bevel, rim, sheen)` 返回 `Card`（x0 y0 x1 y1 w h cx cy r）。blur 是磨砂程度（约 20–30）；tint 是白纱（约 0.24，近光源一侧厚）；sat 是透过来的颜色饱和度（约 1.5）；bevel 是边缘斜面，向外折射，各色通道偏移不同，带很淡的色散；rim 是朝光边的高光描边；阴影只落在卡片外，颜色取自下面的背景。`pill()` 是小玻璃胶囊（按钮、提醒、高亮行，玻璃叠玻璃），`cloud(cx, cy, w)` 是玻璃云
- 形状（带符号距离场，1 px 解析抗锯齿）：`rrect()`、`circle(ring=线宽)`、`line(点列, smooth)`，都可以传 `grad=色阶, angle=`；`divider()` 是蚀刻细线
- 控件：`toggle(x, y, on)`、`slider(x0, x1, y, value)`、`knob()`、`ring(cx, cy, r, width, frac)`（从 12 点顺时针，锥形渐变、圆头、光晕、末端白点）、`check(cx, cy, r, 'done'|'now'|'todo')`、`bars(x0, y0, x1, y1, values, labels=, highlight=)`、`spark(x0, y0, x1, y1, values, dots=)`（返回各点坐标）、`sun()`、`app_icon(x, y, size, grad, glyph)`
- 文字 `text(s, x, y, size, fill, weight='light'|'regular'|'medium'|'semibold'|'bold', anchor, alpha, spacing, grad)`：西文用 SF（按字号调光学尺寸），中文用苹方，自动分段；anchor 第二个字母 s 基线、m 居中、t 顶、b 底；`text_width()` 量宽度
- 颜色：`INK` 深靛文字；渐变色阶 `WARM`（杏→粉→紫）、`COOL`（天蓝→长春花→紫）、`MINT`；`ramp(t, stops)`、`mix()` 在 OKLab 里插值。一种渐变只代表一件事
- `save('x.jpg')` 默认 quality 88、4:4:4 色度

**包豪斯几何 `Bauhaus`**：
- 思路：画面是一张丝网印刷的印张，每种颜色一块网版，先浅后深逐版刮印；同一色版上的所有东西共享这块版的套准误差（平移加极小旋转），所以色块和黑线相接处会露出一丝纸白或压出一道深边
- 纸：`paper(colour, margin, module)` 奶油色未涂布纸（云状纸浆、短纤维、纸屑、纸齿、微微不平的受光），同时设定设计区和网格模数；`at(col, row)` 网格坐标转像素；`grid()` 用浅灰色版印构成网格
- 遮罩（全画布、抗锯齿，可以相加相减）：`circle()`、`ring()`、`sector(cx, cy, r, a0, a1)` 半圆和四分之一圆、`arc()`、`rect(x0, y0, x1, y1, rot)`、`bar(x0, y0, x1, y1, width, cap='butt'|'square'|'round')` 粗黑条和细线、`poly()`、`triangle(x0, x1, base_y)`（默认正三角）
- 印刷：`pull(mask, ink, knock, edge, density, opacity)` 刮一版：墨膜顺刮板方向有条纹、行程末端变薄，薄处露出纸齿坑点，网版灰尘留针孔，版边有网目锯齿、边缘略积墨；墨半透明（黄最透、黑最不透），叠印变深。`knock` 是挖空遮罩，`edge=0` 让细线保持干净
- 文字：`text(s, x, y, size, ink, font, anchor, spacing, rot, weight)` 直接印；`text_mask()` 取遮罩用来挖空；font 用 geo（Futura Bold）、geo_book、geo_cond（窄体特粗）、cjk（粗黑体）、cjk_book，中西文逐字换字体；`text_width()` 量宽度
- 印刷标记：`marks(targets, crop, bar, inks, overprints)` 套准十字、四角裁切线、色标条。登记后每块色版第一次刮印时自动印上自己那一份，所以十字会叠成几色错开的样子
- 印完之后：`pencil(s, x, y, size)` 页边铅笔版号，石墨只挂在纸齿凸起上
- 颜色常量 `YELLOW RED BLUE BLACK`，纸色 `PAPER`，网格色 `TINT`；角度逆时针为正，0° 指 3 点钟；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**复古 Synthwave `Synthwave`**：
- 思路：
  - 一台水平针孔相机看向无限平地（X 右、Y 上、Z 向前，单位米），颜色缓冲从远到近画；
  - 会发光的东西同时写进发光缓冲，后画的不透明物会挡掉身后的光；
  - 最后四个半径泛光，过曝的通道溢向白色，成片再「过一遍录像带」
- 构造：`Synthwave(W, H, seed, horizon=610, vp_x=1060, focal=1100, eye=3.5, record=True)`；相机工具 `project(X, Y, Z)`、`ground_row(Z)`
- 天空：`sky(stops, ground)` 暮色渐变，地平线下先铺没点亮的地面；`stars(n, bright)` 越近地平线越稀，最亮的带四角星芒；`streaks([(y, x0, x1, 厚)])` 底边被照亮的细条云
- `sun(x, y, r, bands=8, band_top, gaps=(0.2, 0.7), level, gain)`：黄→橙→粉渐变落日，横条切口越往下越厚，切口是真缺口；在地平线处截断
- 远景：
  - `mountains(x0, x1, z0, z1, height, cell, taper, edge=(MAGENTA, CYAN))`：世界坐标里的抖动网格高度场，三角面暗色平涂，边线从山脚品红渐变到山脊青色；
  - `skyline(X0, X1, Z, heights, widths, tall=(X, 高), windows)`：远处小城剪影、窗光、航空红灯
- 地面：
  - `floor(colour, spacing, width, fog, scroll, x_range)`：霓虹网格，逐像素解析线宽，远处换成平均值防摩尔纹，带粉色地雾和太阳光带；
  - `sea(coast, bar, spread, sky, glitter, stretch)`：X < coast 一侧的海，倒影碎成一条条光带；
  - `road(x0, x1, dash)`：光滑路面加霓虹边线和中心虚线；
  - `neon_line(X, colour, width, dash)`：地上任意一条纵向霓虹线（海岸线）
- 物件：
  - `palm(X, Z, height, lean, fronds)`：棕榈剪影，环节树干、仰角不一的叶柄、下垂小叶、椰子、朝太阳一侧的轮廓光；
  - `car(X, Z)`：背影跑车，整条尾灯和路面上的红色倒影
- 字：
  - `chrome_text(s, x, y, size, depth, glints=(字序号...))`：镀铬大字，深色描边、阶梯挤出、发光浅边，上映天空、下映地面，中间一道锐利地平线，左上打光的倒角和四角星闪；
  - `glint(x, y, length)`：单独一个四角星闪；
  - `neon_script(s, x, y, size, colour, rot)`：霓虹手写体；
  - `caption(s, x, y, size, colour, rules)`：字距拉开的小字加两侧细线
- 录像带：
  - `osd(s, x, y, px, anchor)`：5×7 块字的录像机屏显（PLAY ▶、日期）；
  - `vhs(bleed, shift_px, jitter, noise, scan, tracking, head)`：只作用于成片，包括 YIQ 色度模糊右移、重影振铃、逐行抖动、一条跟踪噪带、底部磁头噪声、掉磁白线、扫描线、黑位抬升；阶段快照保持干净
- 颜色常量 `MAGENTA CYAN VIOLET ORANGE YELLOW PINK RED WHITE`；字体用 `synth_font('chrome'|'script'|'caption', size)` 找系统字体（Avenir Next Heavy Italic / Brush Script / 冬青黑体），可用 `INKPAINT_FONT_CHROME` 等指定；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**拼豆 `Perler`**：
- 思路：整张桌面是高度图，每样东西都是实体（豆是带孔短管、钉板带钉子、纸有厚度），相机略向后仰：每个屏幕像素沿自己那一列找最近的表面，所以豆子露一条侧壁、缝里露出后排侧面、孔里看得到内壁和钉子。光是左上一个大灯箱：局部点光、沿高度图步进的软阴影、天光 AO，镜面反射里看得到灯箱（亮面上是锐利的弧，熔化后变成蜡质光泽）；线性空间着色，`ss` 倍超采样
- 构造：`Perler(W, H, seed, pitch=22, tilt=0.32, ss=2, light=(x, y, z))`；pitch 是珠距（像素），tilt 是后仰量
- 桌面与纸：`desk(颜色, kind='wood'|'mat')`；`chart(rows, key, cx, cy, cell, angle, title, subtitle, number, names, done)` 印好的图纸（格子、符号、行列号、每 5 格粗线、图例带颗数），返回对象的 `.done.update('RD')` 用铅笔勾掉已摆的颜色；`tape(字, cx, cy, angle, size, sub, badge='1')` 美纹纸标签；`sheet(draw, cx, cy, angle, thick, translucency, drape, cut, curl, bump)` 任意薄片
- 钉板与豆：`pegboard(cx, cy, cols, rows, shape='square'|'circle'|'hexagon', colour='clear'|'white'|颜色, angle)` 返回 `Board`（钉子都在方格点上，`xy(row, col)` 取钉子位置）；`place(board, rows, key, at=(行, 列), only='RDP', keep=lambda r, c: ...)` 按文字图样插豆，可按颜色、按区域分批；key 的值用 `BEADS` 色名（含 `pearl` 珠光、`clear` 透明、`glow` 夜光）或 '#rrggbb'
- 熨烫：`ironing_paper(cx, cy, w, h, angle, cut=((x, y), (nx, ny)), curl, wrinkle)` 盖在豆上的半透明熨烫纸，cut 表示揭开一半（卷边），wrinkle 是热皱；`iron(board, melt, where)`：0.4 半熔，0.7 成品，0.8 全平；`lift_off(board)` 取下成品
- 道具：`tray(cx, cy, [[色, ...], ...], cell, angle, fill)` 分色收纳盒（每格一堆豆）；`spill(cx, cy, colours, n, spread, standing)` 散豆；`bead(x, y, 颜色, pose='stand'|'side', angle, tilt)`；`tweezers(tip, angle, length, lift, rise, holding='sky', grip)` 悬空的镊子，尖端夹一颗豆，自带投影
- 层次与动画：`on_top(*objs)` 提到最上层，`remove(obj)` 拿走；`stage(name)` 只存快照，`save(path, stages_dir)` 时才按 1× 渲染各阶段
- 颜色常量 `BEADS`；角度逆时针为正；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**岩画 `Petroglyph`**：
- 思路：岩画不是画上去的，是把岩面的深色皮（沙漠漆）敲掉。一切都是高度（px）和颜色场，最后用左上一盏低角度侧光照亮：法线明暗、沿光线步进的投影（每个凹坑左上壁暗、右下壁亮）、凹处的 AO
- 构造：`Petroglyph(W, H, seed, light=(-0.62, -0.5, 0.6))`
- 岩石：
  - `rock(colour, relief, bedding, grain)`：砂岩高度图（大起伏、时有时无的层理、砂粒、浅凹坑）和漆下的石色；
  - `ledge(y, drop=34)`：一道折线岩檐，下面的岩面退后一个台阶、漆更薄；
  - `varnish(strength, streaks, top, scour, patches)`：沙漠漆，近乎均匀的深色漆膜 + 清晰的蓝黑流痕 + 浅色流痕，顶部更厚、近地面被风沙磨薄；
  - `fracture(pts, width, depth, seep, branches)`：裂缝，锯齿窄槽、圆肩、分叉，往下渗出深色漆痕
- 起稿：`draft()` 返回 `Draft`（`stroke(pts, w, end_w)`、`fill(pts)`、`dot`、`ring`、`add(mask)`）；现成图形都返回 Draft，可用 `into=` 合成一个：
  - `bighorn(x, y, size, facing, kind='ram'|'ewe'|'lamb', gait, rot)` 大角羊（扭转透视的角）；
  - `hunter(x, y, size, facing, weapon='bow'|'atlatl')` 拉弓 / 举投矛器的猎人；
  - `sun_spiral(x, y, r, turns, rays)`、`crescent(x, y, r, thick, rot)`、`concentric(x, y, r, rings)` 水源；
  - `hand(x, y, size, rot, outline, spread)`、`hoofprints(pts, size, every)` 偶蹄印、`meander(pts, width, smooth)` 任意线
- 凿与磨：
  - `peck(glyph, density, size, depth, age, scatter)`：用成百上千个不规则凹坑把图形敲出来，打穿漆层、碾白砂粒；
  - `abrade(pts, width, depth, age)`：磨出 V 形槽（比凿点光滑、发亮，带顺向擦痕）；
  - `abrade_tally(x, y, counts, gap, length, width, row_gap, slant, age, strike_every)`：成排计日刻痕
- 年代：`age` 0 新凿（亮、锐），0.3 几百年，0.6–0.8 几乎被漆重新盖住；新图凿在旧图上自然更亮、更深
- 风化：`spall(pts, depth, impact, age)` 剥落（小贝壳弧唇口、台阶投影、贝壳状波纹、鲜橙石面，带走上面的图）；`lichen(x, y, r, kind='green'|'orange'|'grey', n)` 壳状地衣
- 顺序：rock → ledge → varnish → fracture → 旧图（age 大）→ 新图 → spall → lichen
- 颜色常量 `STONE SCAR CRUSH VARNISH_FE VARNISH_MN LICHEN`；`stage(name)` 立即合成快照；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**古埃及墓室壁画 `TombPainting`**：
- 思路：先「声明」整面墙上的东西，再按古代画工的工序一遍遍画：`wall()` 草筋泥上抹一层石膏灰泥 → `grid(box, cell, base)` 红赭石弹线的比例格（一格是人物的一个比例单位，脚底到发际 18 格）、`guide(p0, p1)` 分栏线 → `sketch()` 红稿 → `ground(颜色)` 绕开人物刷底色 → `colour([颜料…])` 一罐颜料画一遍、`ink()` 最后勾线 → `colour(layer='text')`、`ink(layer='text')` 写字 → `age()`。每一层都留在内存里，剥落时按层露出来
- 部件：`part(pts 或 [多边形…], 颜料, paths=, ink=, width=, z=, alpha=, clip=, layer=)`；颜料名见 `PIGMENTS`（skin 男子红赭、skin_f 女子黄赭、linen、white、yellow 雌黄、blue 埃及蓝、lblue、green、dkgreen、lgreen、red、brown、ochre、black）；按逐像素 z 图叠放，所以按颜料分批画也不会叠错；勾线被上层遮住的部分自动不画
- 人物：`figure(x, 地线y, 身高, pose, facing, sex='m'|'f', wig='short'|'long'|'woman'|'cap', dress='kilt'|'long'|'loin'|'dress', collar)`；`POSES` 有 stand / walk / staff / plough / reap / sow / hoe / glean / carry / hold / scoop / squat，任一关键字都可覆盖（髋 hip、前倾 lean、膝 kf/kb、踝 af/ab、腕 wf/wb、肘弯向 bf/bb、手型 hf/hb、`turn`、脚镜像 `mb`）；返回手、腕、肩、耳的画面坐标和 z（`hand_f`、`z_hand_b`…），`S((x, y))` 把比例单位换成画面坐标，用来挂道具
- 道具：`staff()`、`sickle()`、`hoe(fig)`、`rod()`、`basket(full=)`、`sack(lean=)`、`heap()`、`measure(tilt=)`、`grain_stream()`、`scoop()`、`papyrus()`、`palette()`；拿在手里的东西 z 给 `fig['z_hand_x'] - 0.01`（从拳头后面穿过）
- 动植物：`ox(x, 地线, 长度, facing, colour, patches)` 长角牛（远侧两条腿错开一步，四条腿都看得见），返回 `poll`（架轭处）；`wheat(x0, x1, 地线, 顶, stubble=[(xa, xb)], grab=[(拳x, 拳y, (xa, xb))])` 麦田、留茬和被攥住的麦秆；`sheaf()`、`tree(waterskin=(dx, 长))`、`papyrus_clump()`
- 边饰：`block_border()` 色块边框、`kheker()` 凯凯尔饰带、`band(x0, x1, y, [(颜料, 高), ('rule', 2), …])` 分栏底带、`river()` 尼罗河
- 文字：`column(x0, y0, x1, y1, facing, n, seed)` 按方块（quadrat）排一栏伪象形文字（高窄的并排、扁的上下叠）；`glyph(名字, x, y, 字号, facing)` 单个符号（`SIGNS` 里 23 个，另有 hoe、stroke、heel、coil）；`numerals(12, x, y, 字号)` 象形数字
- 岁月：`age(losses=[(x, y, rx, ry)], zones=[(x, y, r)], cracks, flake, soot, fade, salt, tide, wear_amt)`：成簇剥落（蓝色和裂缝边先掉）、剥到灰泥露出红格红稿、颜料磨薄、灰泥脱落到草筋泥（断续白边、台阶、投影）、裂缝、埃及蓝发灰绿、顶部烟熏、墙脚潮痕和盐霜、蝇斑、灯光暗角
- `stage(name)`、`save(path, stages_dir)`；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**罗马马赛克 `Mosaic`**：
- 思路：工匠先画一张谁也看不见的「底稿」（cartoon，平涂和渐变的颜色图），再一块块铺石子：每块石子取自己脚下底稿的平均色，从石料盒 `STONES` 里挑最接近的一种（先比色相再比亮度，带一点抖动，色阶交界像工匠混用两种石子）。石子的排向（andamento）就是画法：每种铺法都沿某个标量场（距离场或坐标）的等值线走一排（marching squares），把一排切成整数块，所以每块略长略短；弯处每块自动成小楔形，急转角处断开换一块；靠近图形脊线的石子停在距离场的脊上，两侧在中线会合。后铺的石子大半压在已铺的上面就不要，压一点就「切掉」并留灰缝（先铺的优先）。渲染是 `ss` 倍超采样的高度场：石面微拱、边缘磨圆（每块石子自己的有符号距离做倒角），灰缝更低、带砂，灰浆床再低；左上方一盏斜光，按材质的漫反射 + 高光，每块石子略有倾斜，所以同色石子明暗不一；石子在灰缝里投影、灰缝有 AO
- 构造：`Mosaic(W, H, seed, tile=13, gap=1.8, ss=2, light, bed, grout, stones=None)`；tile 是背景石子边长，gap 是灰缝宽（px）；图形里用更小的石子（size 约 6–8）
- 底稿与起稿：`paint(mask, 颜色)`；`shade(mask, c0, c1, p0, p1, gamma)` 线性渐变（鱼背深、肚白）；`sinopia(mask=… 或 pts=…)` 在湿灰浆上用赭红起稿，没铺到的地方一直看得见（动画第一帧）
- 遮罩：`poly_mask(pts)`、`ellipse(cx, cy, rx, ry, rot)`、`rect()`、`band(pts, w0, w1)` 渐细粗线（触手、船尾柱、浪尖）；`everything()` 已铺的，`free(region)` 还空着的
- 铺石子（按调用顺序，先铺的优先，要保持完整的先铺）：
  - `point(x, y, 颜色, size, 'round'|'square'|'tri', angle)`：单块（眼珠、隔字点）；
  - `line(pts, 颜色=None, size, across)`：沿路径一排（字的笔画、鳍线、桅杆、索具、网线）；颜色 None 时从底稿取色，做触手的中脊；
  - `outline(mask, 'black', rows, size)`：图形内侧的第一排深色轮廓；
  - `fill(mask, size, stones, wrap=True)`：沿轮廓往里一排排铺（opus vermiculatum）；wrap 让石子也绕着已铺的眼睛、鳃线一圈圈排；`figure()` = outline + fill；
  - `halo(region, rows, size, stones, around)`：背景里贴着图形外轮廓的一两圈「光环」；
  - `rows(region, size, angle, wobble, field, stones)`：背景平铺（opus tessellatum）；给 `field`（H×W）就沿它的等值线排，海水用波浪场；
  - `frame(x0, y0, x1, y1, width, size, stones)`：平行于矩形四边的边框排，转角斜接；带宽取排距的整数倍，黑白镶边就和排对齐；
  - `tuck(region, size, small)`：剩下的洞用切小的碎石补上，大洞先补
- 铭文：`letters(文字, x, y, 字高, 颜色)` 罗马大写（A–Y 常用字母，U 写作 V，无 J K W Z），每一笔一排石子，`·` 是三角隔字点；`tabula(x0, y0, x1, y1, [(文字, 字高, 颜色)], ear, frame=('black', 'red'))` 带燕尾耳的铭牌（tabula ansata）：字、黑框、红框、白底横排、红耳
- 岁月（最后做）：`lacuna(mask)` 一片石子脱落，露出旧灰浆床和石子留下的方坑；`crack(pts)` 沉降裂缝（穿过石子和灰缝的黑细线，带凹陷）；`patina()` 灰缝成片积灰、局部失光
- 石料：`STONES` 名字 → (颜色, 材质)，材质 stone（石灰石，哑光、斑驳、麻点）/ marble（纹理、微光）/ glass（smalti 玻璃，饱和、亮、带气泡）/ terracotta；`stones=[…]` 限定这一步能用的石料（天空只用 white / bone / cream，海只用蓝色玻璃）
- 工具函数：`edt(mask)` 跳步泛洪欧氏距离场、`iso_lines(f, step)` 一次求出所有等值线、`maxfilt()`；`STONES MATERIALS LETTERS SINOPIA`
- 动画：`stage(name)` 只记进度，`save(path, stages_dir)` 时按 `stage_ss`（默认 1×）渲染各阶段和收尾帧；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**彩色玻璃花窗 `StainedGlass`**：
- 思路：照玻璃匠的工序——画稿分块 → 选料切玻璃 → grisaille 彩绘、刮白、银染 → 上铅焊接 → 装铁条 → 从室内看日光透进来。颜色全在玻璃里，颜料只有一种棕黑；铅条落在每两块玻璃的交界上
- 构造：`StainedGlass(W, H, seed, record=True, ambient=0.05)`；`stage(name, cartoon=False)`（cartoon=True 出纸上的切线画稿）；`save(path, stages_dir)`
- 石墙：`wall(colour, mortar, course, block)` 错缝方石墙（每块石料深浅不同、斜向凿痕、磨损的棱、凹进的灰缝）；`lancet(cx, top, bottom, width, arch=1, splay, sill, hood)` 开一个尖拱窗洞，返回 `Light`，带斜面窗侧（拱上是放射状楔石缝）、斜窗台、拱上的滴水线脚；`string_course(y, h)` 腰线
- `Light`：`pt(lx, ly)` / `P(点列)` 把局部坐标（原点在拱尖，y 向下）换成画面坐标；`inner(b)` 向内缩 b 的窗形遮罩；`band(b0, b1)` 沿窗边的一圈带（边框、白条）；`outline(b, step)` 沿窗边取点（给边框切块）；`sdf()`；`half(ly, b)` 某高度的半宽
- 玻璃：`glass(遮罩, 颜色或颜色列表, cell, streak, seeds, thick, vary, flashed, aspect, angle, around, spokes, sites, streak_dir)`。颜色是透光时的样子；给 cell 就按 Voronoi 切块，每块从列表里取一种颜色、深浅厚薄各不相同；sites 按给定点切（边框、长条）；aspect / angle 把块拉长；around 绕一点放射切；flashed 是红色套料那种强条纹。后铺的料从先铺的里切出来；太小太窄的碎块自动并进同料的邻块。`cut(点列)` 加一道切线
- 遮罩：`circle()`、`ellipse()`、`poly()`、`blob()`、`branch(点列, 起宽, 止宽)` 渐细的枝
- 彩绘：
  - `trace(点列, width, taper, opacity, clip)` 不透明描线（五官、叶脉、羽毛、细枝），clip 限定只画在某个遮罩里；
  - `matt(遮罩, strength, soft, stipple)` 半透明晕染，带点彩颗粒；`shade(遮罩, offset, strength, clip)` 背光一侧的月牙形 matt；
  - `scratch(点列, width)` / `scratch_mask(遮罩)` 用木签刮掉颜料，让光透出来；
  - `diaper(遮罩, spacing, motif='cross'|'dot'|'ring'|'flake'|'quatrefoil', jitter)` 底纹，默认从一层薄 matt 里刮出，jitter 撒开就是雪花；
  - `stain(遮罩, strength)` 银染：白料变柠檬黄到琥珀，蓝料变绿；
  - `inscribe(字, x, y, size, font='lombardic', scratched)` 题字（Luminari / Herculanum，可用 `INKPAINT_FONT_LOMBARDIC` 指定）
- 上铅与铁件：`lead(width=6, rim=10, solder=True)` 在每条交界上铅（按 H 形铅条打光，焊点更亮更鼓，窗边一圈宽铅）；`crack(点列, mend=True)` 裂片和修补用的细铅条，要在 `lead()` 之前；`saddle_bar(light, y, width)` 横铁条（y 是画面坐标），两端插进石头，扎几处铜丝结，要在 `lead()` 之后
- 光：`weather(grime, pits)` 铅条边和窗下部积灰、部分玻璃的腐蚀麻点；`daylight(strength, spill, halation, sky)` 打开室内光：墙上一层彩色溢光、窗侧斜面靠玻璃处发亮、斜窗台上倒过来的模糊投影、亮玻璃的光晕吃掉一点铅条（蓝色最明显）。`daylight()` 之前墙用固定的中性光，阶段快照之间石墙不变
- 颜色常量 `RUBY BLUE DEEP_BLUE SKY GREEN LEAF SPRING OLIVE GOLD AMBER ORANGE MURREY WHITE PALE BROWN FLESH`；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**泥金手抄本 `Illuminated`**：
- 思路：
  - 按作坊顺序作画：打格 → 抄写（红字和首字母留空）→ 朱笔 → 画图 → 贴金 → 上色 → 勾线；
  - 字是一支模拟的宽头鹅毛笔写的：笔尖是一段约 40° 斜握的短线段，笔画就是它扫过的面积，所以粗细随行笔方向变；菱形的头脚和发丝般的连笔都来自笔，不来自字体；
  - 打磨金箔是凸起石膏底上的一面镜子：每个像素按自己的法线（石膏底的鼓面、打孔、金箔接缝、打磨纹）反射相机光线，去查一间左上方有大窗的房间；
  - 壳金是哑光的颗粒；
  - 先贴金后上色，后画的颜料和墨会盖住金。
- 书和皮：
  - `desk()` 胡桃木书桌；
  - `codex(x0, y0, x1, y1, cover, squares, stack, dip)` 摊开的书（皮面封板、书口纸叠、页面在书脊处下陷变暗），返回左右两页的矩形；
  - `flaw(cx, cy, rx, ry, rot)` 羊皮上的天然破洞；
  - `rule(x0, x1, ys, prick_x)` 针孔、每行 x 高处的打格线、上下贯通的边框竖线；
  - `show_through(x0, x1, ys, xh, opacity)` 背面的字透过来。
- 文字：
  - `column(text, x0, x1, y, xh, leading, indent=[(行数, 左边 x)], align, filler)` 排一栏，返回 Block：
    - 标记 `*红字*`（留给朱笔）、`^词`（首字母点红）、`¶` 段落符、`|` 段落结束；
    - 自动长 s / 圆 s、断词加连字号、行尾填充；
    - `7` 写成提罗速记的 et（⁊），`ꝑ` 是 per。
  - `scribe(blk, dip)` 抄写黑字：每隔若干字重新蘸墨，铁胆墨由黑变褐，笔画边缘积墨；
  - `rubricate(blk, blue_first)` 朱红字、首字母点红、红蓝交替的段落符、行尾红锯齿加蓝点；
  - `write(s, x, y, xh, kind, rot, load)` 写一行，返回行尾 x；
  - `arc_text(s, cx, cy, r, at, xh, kind)` 沿圆弧书写；
  - `text_width()` 量宽度；
  - kind 可选 'iron' / 'red' / 'blue' / 'white' / 'diagram'。
- 金和颜料：
  - `gild(mask, cushion)` 红色底料上的凸起打磨金；
  - `punch(pts, r, depth)` 打孔装饰；
  - `shell_gold(mask)` 壳金；
  - `paint(mask, 颜色, mix=(颜色2, 0..1 场), granular)` 蛋彩，边缘积色，石青有颗粒；
  - `wash(mask, 颜色, opacity)` 透明淡彩；
  - `pen(paths, width, kind, dash)` 圆头笔线；
  - `outline(mask, width)` 沿形状描墨边。
- 遮罩：`mask(polys, lines, dots, holes)`、`circle()`、`ring()`、`ellipse()`、`star()`。
- 装饰物件（按作坊顺序调用各自的 `.draw()`、`.gild()`、`.paint()`、`.pen()`）：
  - `initial('Q'|'O', x0, y0, size, body)` 历史化首字母：伦巴第体字身配白线描、打孔金底、字腔里的夜景；
  - `border(path, width, avoid, bounds, seed, every, reach)` 金 / 群青 / 玫瑰色条形边框，递归长出常春藤花枝（金叶、花、金珠、卷须），避开 avoid 矩形；
  - `versal('O', x, y, size, colour, flourish, reach)` 两行高的分裂伦巴第字配红色花笔；
  - `astrolabe(cx, cy, R, lat, rete, rule, star)` 星盘；`.pen(labels=[(字, (x, y), (指向的 x, y))])` 加红色标注；
  - `spheres(cx, cy, R, angles, label_at)` 诸天圆图。
- 收尾和输出：
  - `age(foxing, soil, flakes, halo)` 六百年：铁胆墨晕、狐斑、翻页手印、金箔剥落露出红色底料、石青崩口；
  - `stage(name)`、`save(path, stages_dir)`。
- 颜色常量 `VELLUM INK RED AZURE ROSE GREEN WHITE SILVER LEAD OCHRE BOLE`；角度逆时针为正；`save('x.jpg')` 默认 quality 88、4:4:4 色度。

**达·芬奇手稿 `Codex`**：
- 纸：`sheet(tone, mount, margin, laid, chain, lost_corner='br', fold=x, stains=[(x, y, r)], foxing, edges, age)`：裱在卡纸上的帘纹碎布纸（帘纹、链线、纤维、纸齿），自带边缘氧化、缺角、泛黄云斑、霉斑、水渍潮线、可选旧折痕、手翻处的污渍；`show_through(x, y, width, lines)` 背面的字透过纸，左右反过来（所以是正着读的）
- 铁胆墨水和鹅毛笔：`quill(pts, width, ink)` / `quills([...])`，笔宽随宽笔尖方向变、落笔重收笔尖；笔里的墨会用完：越画越淡，再蘸一次又变浓，偶尔在落笔处积一个小墨珠；`contour(pts, searching=2)` 先轻轻找两三遍再定线（修改痕）；`ruled(p0, p1)` 靠尺直线；`dotted(pts, dot_dash=True)` 虚线 / 点划线（轴线）；`arrow(pts)`
- 排线：`hatch(mask, shade, angle=55, spacing, levels=(…), cross=0.76, cross_angle=-38, length, origin, medium='ink'|'chalk')`。55° 是左撇子的「\」；shade 0 亮 1 暗，每多一级 level 就在两线之间再插一层，超过 cross 加一层「/」交叉；按「排」下笔。明暗场：`between(a0, a1, b0, b1)`（从一条线到另一条线 0→1，蒙皮、圆杆）、`radial_shade(cx, cy, r)`；遮罩：`poly_mask(pts)`、`disc_mask(cx, cy, r)`、`Codex.arc(cx, cy, r, a0, a1)` 取弧上的点
- 红粉笔和铅笔：`sanguine(pts, width, pressure)` / `sanguines([...])` 只挂在纸齿上，`rub(mask, amount)` 用手指揉开；`leadpoint(pts)` 淡灰的铅笔起稿
- 尖笔和圆规：`incise(pts)` 无色的刻痕（侧光下一边亮一边暗），`compass(cx, cy, r, a0, a1)` 刻圆弧并在圆心留针孔，`prick(x, y)`
- 常画的东西：`cane(p0, p1, w0, w1, bend, lashings)` 两条线画的藤杆 / 木杆加绑绳，返回轮廓用来挖掉排线；`feather(base, angle, length, width, medium, side, overlapped)` 羽毛（返回轮廓、羽轴、宽羽片外缘）；`bird(x, y, size, phase)` 背视的小飞鸟，phase 从 π/2（翅膀最高）到 −π/2（最低）
- 镜像手写：`write(文本或行列表, x, y, width, size, mirror=True, max_lines)`，mirror 时 x 是右边距、每行从右往左写、左边参差；`prose(n)` 生成意大利语伪文；`label('a', x, y)` 字母标注（`mirror=False` 写正字，如收藏者的页码）
- 意外：`blot(x, y, r)` 带深色潮线和小溅点的墨点、`spatter(x, y, n)`、`strike(x0, y0, x1, y1)` 划掉废稿
- 机械零件（笔绘渲染）：`Camera(cx, cy, scale, azim, elev)` 正交相机；零件 `gear(r, teeth, depth, h, hub)`、`lantern(r, h, staves)` 灯笼齿轮、`crown(r, h, teeth)` 冠齿轮、`crank(arm, r_axle, handle_len, handle_r)`、`pulley(r, h)`、`cylinder()`、`box()`、`extrude()`；`.place(origin, axis, spin)` 摆放、`.named('wheel')` 命名表面组、`merge(...)` 合成一个网格；`solid(mesh, cam, hatch=dict(...), hatch_groups={'wheel.face': dict(...) 或 None})`：z-buffer 去掉被挡住的线、先擦掉身后的墨、按每个面背光的程度排线、只描轮廓 / 折边 / 开口边并连成长笔画；分解图就是把零件沿轴拉开再画点划线
- 颜色常量 `INK_DARK INK_LIGHT SANGUINE LEADPOINT PAPER MOUNT`；字体自动找 Apple Chancery / URW Chancery（Linux）/ Segoe Script（Windows），可用 `INKPAINT_FONT_CHANCERY` 指定；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**剪影 `Silhouette`**：
- 思路：剪影是黑纸用小剪刀剪出来的，贴在象牙白卡纸上，用薄金粉描几笔，装进玻璃椭圆金框挂到墙上。墙纸、金框、玻璃都按真实材料做，左上方一扇窗照亮整面墙
- 墙：`wallpaper(ground, ink, tint, period, repeat, length)` 木版印花条纹墙纸（刷涂的胶彩底、两块印版、错版、干斑、定位针点、每幅纸对花略错、拼纸接缝）；`picture_rail(y, h)` 挂镜线；`chair_rail(y, h, dado)` 护墙线和下面的墙裙
- 框：`frame(cx, cy, rx, ry, width, pearls, twist, eglomise, card, hook, cord, spread)` 返回 `Frame`。按线脚剖面建高度图（内口圆珠、凹槽、一圈珠饰、大圆脚、平条、外圆边；`twist` 把大圆脚做成绳纹），金面反射房间环境（窗亮、屋暗、地黑），所以出现一圈圈明暗环；有金箔方块接缝，棱顶磨出红色底漆，凹处积灰；墙上有接触阴影和柔影。`hook=True` 从挂镜线铜钩垂下两股丝绳（V 形，伸进框后面）；卡纸边缘泛黄、带霉斑；`eglomise` 是玻璃背面的黑底金线圈
- 剪纸：`sheet(f, at, scale, flip, warp)` 返回 `Sheet`，坐标用设计单位（px = at + scale × 点）；`warp` 是一个函数，可以整体改比例（头大一点、身子短一点）：
  - 贴平的主体：`shape(pts)` 主轮廓（只有一丝影子，边缘重采样成一小段一小段剪口）、`disc(x, y, r)`；`hole(pts)` 剪空，露出卡纸（眼睛、腿间、蝴蝶结的缝）
  - 单独剪下、微微翘起、影子更长的细条：`snip(pts, w0, w1)` 渐细的条（睫毛、胡须、发丝、飘带，宽度可传数组）；`line(pts, w)` 等粗的条（缆绳、桅杆）；`fringe(pts, n, length, angle, width, side, bend)` 沿曲线一排细丝（鸵鸟羽毛的羽枝、胸前的毛）；`scallop(pts, r, outset)` 一排鼓出的小圆（卷发团、帽冠抽褶、收起的帆）；`ringlet(x, y, length, width, turns, sway)` 螺旋垂卷，返回中线给金粉用；`lace(pts, depth, step)` 带一排穿孔的蕾丝花边
- `paste(sheet)` 把剪好的纸贴到卡纸上：4× 超采样再缩小，1 px 的细丝也留得住；黑纸带纤维和光泽，朝光的剪边有一道细亮线
- `bronze(sheet, strokes, width, tip, bright)` 薄金粉：每笔渐细、亮度各不相同、带颗粒，只留在黑纸上
- 字：`caption(f, 文字, x, y, size, style='roundhand'|'italic')` 铁胆墨手写题签（`sil_font` 找 Snell Roundhand / Baskerville Italic，可用 `INKPAINT_FONT_ROUNDHAND`、`INKPAINT_FONT_ITALIC` 指定）；`pen(f, pts)` 墨线
- `glaze()` 装上玻璃：凸面玻璃的柔光和窗户倒影；`smooth(pts, per, closed)` 闭合或开放的 Catmull-Rom 曲线
- `stage(name)`、`save(path, stages_dir)`；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**凸版印刷海报 `Letterpress`**：
- 思路：每种油墨一块版（forme），先把要印这个颜色的东西都「锁」进版里，`press(ink)` 一次压印。每过一次机器纸张落得不一样：每块版有自己的平移和极小旋转（`register(ink, dx, dy, rot)`），红版和黑版永远对不齐。先红后黑
- 纸：`paper(colour, warm, tone)`：已经泛黄的廉价海报纸（云状纸浆、短纤维、杂点、纸齿、微微不平）
- 版：`lock(mask, ink, film)` 锁进任意遮罩；`clear(mask, ink, keep)` 刻掉（木刻高光、前后遮挡）；`with lp.layer('key'):` 把东西锁进版的某一部分，`press(ink, only=['key'])` 只压这一部分（阶段动图先出轮廓线、再出排线）；`press(ink, density)`：边缘随纸齿参差、边上积一圈深墨、大实地缺墨发花并露出纸齿白点、灰尘留下圆形漏印；黑压红更深
- 木活字：`type_line(s, x0, x1, base, cap, face, ink, align='justify', stretch, track, shade=(dx, dy, 另一版颜色, gap), inline=(inset, width), wear, grain, limits)`：默认把一行排满版心（字面横向压扁或拉宽、再加字距），每个字是一块木头：木纹条痕、一端偏浅、凹坑软斑、边角缺口、偶尔一道顺纹裂缝；shade 是印在另一块版上的投影，inline 是笔画中间刻一道白线。face 用 clarendon / antique / gothic / fatface / cjk（宋体黑）；`type_width()` 量宽度
- 铅字与花饰：`text(s, x, y, size, face='roman'|'roman_bold'|'italic'|…, ink, anchor, spacing, rot, stretch)`、`text_mask()`、`text_width()`；`rule(x0, x1, y, kind='single'|'double'|'thick_thin'|'thin_thick'|'dotted', ink, weight, joints)` 铜线（长线由几段拼成，接头有细缝和 1 像素错位）；`leaders()` 引线点；`star()`；`ornament(字符, ...)` 花饰字体（缺字体时画星）；`border()` 粗细双线框加方角
- 形状（整页浮点遮罩，可加减乘）：`shape(控制点)` 平滑闭合曲线、`poly()` 直边多边形、`tube(点列, widths=[...])` 变粗细的管子（腿、鼻、尾、绳）、`ellipse(cx, cy, rx, ry, rot, a0, a1)`、`rect()`、`outline_pts()`
- 木刻：`key(mask, width, heavy)` 轮廓线刻在形状内侧、背光一侧加粗；`hatch(mask, angle 或 centre+aspect, spacing, tone, lo, gain, wobble)` 线宽随明暗变化的排线，tone 低于 lo 处收尖消失、高处并成实地；`form_tone(mask, soft)` 把遮罩当成鼓起的体积打光得到 tone；`ramp(p0, p1)` 线性渐变 tone；`cast(mask, dx, dy, onto)` 投影；`line(pts, width, taper)` 两头收尖的刻线（皱纹、绳子）；`solid()`；`stipple(mask, density, size, tone)` 点刻；`tint(mask, ink=RED, loose, grow)` 另刻的套色块，边缘游走、比轮廓略胖
- 印后：`fold('v'|'h', pos, depth, crack)` 折痕（油墨裂开、积灰、两侧受光不同）；`tone_edges()` 边缘泛黄；`foxing(n)` 霉斑；`stain()` 水渍；`tack(x, y, r)` 钉孔和锈斑；`nicks(n, size)` 纸边缺口；`strip(x0, y0, x1, y1, rot, colour, draw=fn)` 另印一条日期条贴上去（fn 拿到一个小 Letterpress 往上排字，周围有浆糊印）
- 颜色常量 `RED BLACK PAPER`；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**苏联构成主义 `Constructivism`**：
- 思路：一张纸、两块版。红的都在红版上，黑的（色块、字、每张照片的每个网点）都在黑版上。画东西就是「把遮罩印到某块版上」或「从某几块版上挖掉、露出纸」。合成时每块版整体带一个套准误差（平移加极小旋转），所以红黑相接处一边露纸、一边叠出深色。墨是透明滤色，相乘叠印，黑压红是暖黑
- 构造：`Constructivism(W, H, seed, misreg=2.4, red=RED, black=BLACK)`
- 纸：`paper(colour, aged, yellow)`：便宜的奶油色海报纸（云状纸浆、纤维、纸屑、微微不平、边缘发黄）
- 遮罩（全画布、抗锯齿，可加减）：`circle()`、`ring()`、`arc(cx, cy, r, a0, a1, width)`、`sector()`、`rect(x0, y0, x1, y1, rot)`、`bar(x0, y0, x1, y1, width)` 斜条或细线、`wedge(apex, angle, half, length)` 楔形、`poly()`；`along(p, angle, d, side)`：从 p 沿某个角度走 d、再往左偏 side，用来摆斜排的字和标注
- 印：
  - `ink(mask, 'red'|'black', knock=, density)`：印一版，knock 是从这块色里挖掉的字；
  - `knock(mask, plates)`：从这几块版上挖空；
  - `tint(mask, plate, level, cell, angle)`：平网；
  - `waves(cx, cy, r0, r1, step, width, a0, a1, plates, grow)`：限定角度内的同心波前，grow 为负时越传越细
- 字：`text(s, x, y, size, plate, font_style='grotesk'|'din'|'narrow'|'futura', anchor, spacing, rot, wobble, scale_x, knock)`；`text_mask()` 用来反白；`text_width()` 量宽度。grotesk 是 Helvetica Neue Condensed Black（退回 Impact / DejaVu Sans Condensed Bold），din 是 DIN Condensed（退回 Arial Narrow / PT Sans Narrow）；缺西里尔字形的字体自动跳过；`wobble` 给大字一点手绘的抖动
- 照片 `Photo(w, h, eye, target, fov, ss, key, fill, haze, shift, ...)`：小型透视 z-buffer 光栅器，单位米，Z 朝上：
  - `material(albedo, gloss, shine, metal, tex, interior)` 返回材质号，tex 是按世界坐标算的程序纹理（木纹、刻度、线圈绕线）；
  - `cylinder()`、`lathe(base, axis, [(t, r), ...])` 旋转体、`sweep(path, radii)` 变径管（鹅颈、喇叭、软线）、`box()`、`hyperboloid(z0, z1, r0, r1, n, twist, mid)` 双曲面网格塔的一节；
  - `project()` 把世界坐标点换成照片像素，用来让海报上的其他元素对准照片里的东西（如楔形对准喇叭口）；
  - `render()` 只调一次：只给有物体的像素着色，渲染后释放缓冲
- 拼贴：`montage(photo, cx, cy, rot, scale, plate, cut, close, backdrop, cell, angle, contrast, soften)`：缩放、旋转、放上去，再在海报坐标里统一加 45° 网点（所有照片共用一张网）。
  - `cut=` 沿轮廓留边剪下：盖住下面已印的东西，露出纸色白边和背景的高光小点；
  - `close=` 桥接剪刀剪不进的窄缝；
  - 不给 cut 就是去了底的照片，网点直接叠印在红色上；
  - `soften` 是加网前的模糊（单位：网格），网格塔这类细杆用 0.12
- 做旧：`age(folds=(竖, 横), foxing, stain, pins, crack, grime)`：折痕裂墨与磨损、霉斑、水渍潮线、磨旧的角、图钉锈孔
- 顺序：paper → 红版色块（圆、楔形、色块）→ 黑色波线、斜条（`knock` 掉下面的红）→ 照片 → 字和标注 → age
- 颜色常量 `RED BLACK PAPER AGED`；角度逆时针为正，0° 指 3 点钟；`stage(name)` 立即合成快照；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**装饰艺术 `ArtDeco`**：
- 思路：画家不画线。每个形状都是一张用刀刻出来的遮片（frisket），盖在板上用喷枪喷色，所以边缘锐利、里面是一段平滑渐变；形体只靠明暗：楼是一张平剪影、一侧喷暗一侧喷亮，圆柱体上肩一道高光、下腹一条反光
- 喷枪：`spray(mask, 颜色或整幅颜色场, density, grain, blend='paint'|'screen'|'add')` 一次喷涂；薄涂处有雾滴颗粒（固定噪声 × d(1−d)），实涂处没有；`fade(mask, stops, p0, p1)` 线性渐变，`glow(cx, cy, r, 颜色)` 径向光晕；遮片 `rect()`、`poly()`、`disc()`（都抗锯齿）；`ramp(t, stops)` 色阶
- 天空：`sky(stops, top, bottom)` 长渐变；`burst(cx, cy, rays, contrast, reach, colour, dark, glow, phase, taper, bottom)` 明暗交替射线（亮楔靠近中心略宽，对比随距离衰减，bottom 处截止）；`moon(cx, cy, r)` 偏心径向渐变的球形月亮、光晕、柔边月海；`searchlight(x, y, angle, length, spread)` 探照灯光束
- 城市：`tower(x, base, [(宽, 高), ...], body, rim, light=±1, flutes, windows, slits, far, spire, spire_w, mast, ledge, top_windows)` 阶梯退台高楼，返回顶层顶部中心；`far` 0..1 推进雾里（变浅变蓝变平）；`crown(x, y, w, steps)` 扇形阶梯冠顶（放射窗），返回顶点 y；`clock(cx, cy, r, 时, 分)` 钟面
- 河：`water(horizon, stops, reflect)` 先喷河面渐变，再把地平线以上已经画好的东西镜像进来，打碎成横向波纹，亮的东西反射更强
- 3D 列车：`camera(f, cx, horizon, height)` 水平针孔相机；`express(nose=(X, Z), vp_x, deck, cars, loco, car, gap, nose_len, rake, light, moon)` 在拱桥上渲染流线型列车（距离场 + numpy 球面步进，只对边缘像素 3×3 超采样），返回分层结果 `r`；按画家的顺序叠上去：`frisket(r)` 遮片平涂底色 → `model(r)` 明暗塑形（半朗伯色阶、上肩喷枪高光带、月光轮廓光、下腹反光、远处雾色）→ `lights(r, beam, beam_len, bloom, reflect)` 车窗（卧铺窗帘拉下一半）、头灯、光束、辉光、灯照铁轨、可选的河面倒影；`project(X, Y, Z)` 世界坐标转像素
- 字：`lettering(s, x, base, cap, fill, track, shadow, anchor)` 库内自建的 Deco 展示字母 A–Z（粗竖笔、发丝横笔、高腰线、椭圆字碗），金属渐变填色（中线一道硬分界），可加块状投影；`deco_width()` 量宽度；`caption(s, x, y, size, colour, track, anchor)` 宽字距几何无衬线小字（返回宽度）；`rule()` 金线；`border(inset, gap, width, step)` 阶梯角双金线边框
- 印刷：`finish(paper, tooth, warm, vignette)` 纸纹、微颗粒、暖色偏、轻微暗角
- 颜色常量 `NAVY MIDNIGHT TEAL JADE GOLD BRASS IVORY CREAM MAROON CRIMSON WARM`；坐标像素、y 向下，3D 世界单位米、y 向上；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**黄金时代漫画 `ComicCover`**：
- 思路：先按当年的分工把封面「做」出来，再按当年的印法「印」出来。墨线师在黑版上勾 key 线；上色师在色稿上给每块区域指定三原色的 Ben-Day 网点比例（0 / 20 / 40 / 70 / 100%），整张封面只有几十种颜色；印刷时每版按自己的角度加网、各自错开几像素，新闻纸吸墨让网点变毛、小点丢失、实地发花；油墨透明相乘。网点和错版都不手画
- 构造：`ComicCover(W, H, seed, screen=11, misreg=4, slop=1.6, light=(-0.6, -0.8))`：screen 是网点间距（px），misreg 是各色版的错位量，slop 是手绘分色的游走量；`register(plate, dx, dy, rot)` 手动指定某版的落点
- 纸：`paper(colour, tone, fibres, flecks)` 泛黄新闻纸（云状纸浆、深浅短纤维、树皮屑、不吃墨的纸坑）
- 形状（整页抗锯齿遮罩，可加减乘）：`mask(pts, smooth)`、`circle()`；静态方法 `ellipse_pts()`、`smooth()`（闭合样条）、`tube_pts(路径, 宽度列表)`（四肢、绳子、围巾、耳朵）、`burst_pts()`（星星、爆炸框）、`edge_normals(pts)`（轮廓点和外法线，给 `feather` 用）；`grow()` / `shrink()`
- 色稿：`flat(shape, 颜色)`，颜色是 (蓝, 红, 黄, 黑) 四个网点比例；`graded(shape, [颜色…], p0, p1, edges=[…])` 沿手裁波浪边分档的色带；`rings()` 同心色环；`knock()` 挖白
- 黑版：`part(pts, 颜色, width, heavy)` 是放前景物件的标准做法：擦掉身后的墨线和颜色、铺色、勾一圈背光侧加粗的轮廓；`brush(pts, width, taper, swell)` 两头尖、中段鼓的毛笔线；`pen()` 细笔；`outline()` / `edge()` 闭合 / 开放轮廓；`ink()` 实黑块；`erase()`；`mask_outline(mask, width, heavy)` 给任意遮罩（圆的并集、字）描边；`feather(P, N, length, width, spacing, clip, along, toward, curl)` 从阴影边长出来的羽状排线；`hatch()` 平行排线；`speed()` 速度线；`dot()`
- 字：`letter(text, x, y, size, face, colour)` 手写字，逐字微转、微跳（face：letter 漫画手写体 / logo 窄粗体 / bold / slab / heavy）；`text_mask()`；`balloon(text, x, y, size, tail, kind='speech'|'yell'|'thought')` 对白框 / 喊叫爆炸框 / 想法云；`caption(x0, y0, x1, y1, text, colour)` 旁白框；`sfx(text, x, y, size, colour, rot, shade)` 拟声字；`logo(text, quad, vp, depth, colours, shade, shadow, glints)` 透视立体刊名：四个角点定透视，朝灭点挤出 depth 像素，正面上浅下深分档，加挤出面、投影、粗黑外框和高光斜纹
- 做旧（印完以后再加，只作用在各自区域）：`brown_edges()` 边缘泛黄；`spine(ticks, staples)` 书脊折痕、白色应力裂纹、两枚生锈订书钉；`corner('br', radius)` 角上磨掉油墨、折角；`crease(p0, p1)` 折痕处油墨裂开露白；`foxing(n)` 霉斑
- 阶段：`stage(name, plates='CMYK')` 记下当时的各版，出图时只印列出的版：先用 'K' 出黑版线稿，再依次 'YK'、'YMK'、'CMYK'，就是印刷厂的「渐进打样」
- 颜色常量（色稿比例）：`WHITE CREAM PALE YELLOW GOLD ORANGE DEEP_ORANGE RED CRIMSON PINK SKIN TAN BROWN DARK_BROWN SKY LIGHT_BLUE BLUE NAVY VIOLET MAUVE LILAC GREEN LIME GREY LIGHT_GREY SILVER`；油墨颜色 `INK`；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**波普丝网 `PopSilkscreen`**：
- 思路：重做 60 年代「工厂」的做法。一张照片做成黑色照相丝网版；一张画布用胶带隔出几格，每格先手涂撞色平涂（底色，再是脸、眼、鼻、项圈……），形状照着照片描得很松、对不准；然后把同一块黑版逐格刮印上去，每格放版的位置、角度和墨量都不同
- 构造：`PopSilkscreen(W, H, seed, light=(-0.55, -0.8))`；`canvas(gesso, thread=3.8, slub=0.18)`：刷了白底漆的棉帆布（平纹布纹高度场、粗节、均匀布光）
- 分格：`grid(cols, rows, gap, margin, origin=(0.5, 0.53), unit=0.285)` 返回 `Panel` 列表。每格里用「单位」作画：origin 是单位原点在格内的位置（宽、高的比例），unit 是每单位占格高的比例
- `Panel` 上取遮罩（局部窗口，四周留 pad 像素，方便渗边和错位）：
  - `shape(pts)`：闭合样条
  - `stroke(pts, w0, w1, profile=)`：渐细笔画，宽度用单位；`profile(t)` 自定粗细
  - `ellipse(u, v, ru, rv, rot)`、`dots([(u, v, r)])`
  - `soft(mask, sigma)`：柔化成给网点用的调子；`blank()`
  - 坐标换算：`at(u, v)` 单位 → 局部像素，`xy(u, v)` 单位 → 画布像素
  - 模块函数：`turn(pts, deg, about)` 屏幕上逆时针转（歪头用）、`mirror(pts)` 左右镜像、`closed_spline()`
- 手涂丙烯：
  - `ground(p, 颜色, direction, bleed)`：一格的底色，刷到胶带为止，有几处渗进胶带下的毛边
  - `paint(p, mask, 颜色, direction, wobble, drift, opacity, dry, streak)`：手涂一块平涂色。wobble 是边缘手抖（px），drift 是这块颜色描偏了多少（px）；顺笔方向有轻微明暗，边缘有干笔拖痕和一道受光的漆脊；只涂在本格里
- 黑版 `key(p, solid, tone, ink, shift, rot, density, flood, starve, pull, nicks, ghost, cell, angle)`，返回印上的覆盖率：
  - solid 是实黑的阴影块；tone 是中间调，印成 45° 粗网点（cell 约 7 px）；照相阈值的颗粒边和膜上的灰尘点自动加；`stencil()` 可以单独取照相版遮罩
  - shift、rot：这一格放版的偏移（px）和转角（度）
  - density：墨量，0.92 缺墨、1.0 正常、1.15 墨多，低于约 0.9 就印不出脸
  - flood：墨多糊版，形状变胖、细缝填死、挤出墨团
  - starve：干在网上的一块墨斑；pull：刮板方向（90 自上而下，0 自左向右）；nicks：刮板缺口留下的细白线
  - ghost=(dx, dy, 强度)：版放了两次，留下一层灰影
- `stage(name)`、`save(path, stages_dir)`；`save('x.jpg')` 默认 quality 88、4:4:4 色度
- 颜色常量（60 年代丙烯撞色）：`HOT_PINK PINK BLUSH RED ORANGE TANGERINE LEMON YELLOW CREAM LIME GREEN MINT TURQUOISE SKY BLUE ULTRA VIOLET LILAC WHITE`，底漆 `GESSO`，黑墨 `INK`

**ASCII 字符画（行式打印机） `LinePrinter`**：
- 思路：画面不直接画在纸上，而是画进一张隐藏的「角色图」（每个字符格 6×10 个采样）：每块区域带一个角色（用哪套字符）和一个调子（要多少墨），后画的盖住先画的；`compose()` 再逐格决定打哪个字：线条格按线的方向和在格里的位置选 \| / \\ _ - . ' X +，剪影转折处同样处理，填色格按调子从角色的字符阶梯里选（同角色内误差扩散），最暗的格用叠打。最后模拟鼓式行式打印机逐行击打
- 构造：`LinePrinter(W, H, seed, cols=132, top=40, cpi=10, lpi=6, form_in=14.875, ss=2, weight='bold', ppi=None, page_in=11.0)`；`top` 是撕线的位置，`ppi=None` 让纸宽撑满画面，调小就整张纸躺在桌上、左右露出桌面；`page_in` 是纸深（11 英寸 66 行，8.5 英寸 51 行，配合 ppi 能让上下两道撕线都入画），`page_rows` 是一页的行数；`rows` 是看得见的行数，坐标一律用（列, 行），可以是小数；`xy(col, row)` / `centre(col, row)` 换算成像素
- 纸：`form(white, green, desk, band=3, first_green, holes)`：14 7/8 英寸宽的绿条连续纸，每 3 行一条浅绿带，两侧导孔（孔里看得到桌面和纸的投影，偶有被拉长的破孔）、微孔撕线、每 `page_rows` 行一道横向撕线和折痕；纸比画面窄时两侧是桌面和纸的投影。要留页边就在 `compose()` 前 `erase(rect(0, page_rows − 2, cols, rows))`
- 角色：`role(name, ramp, edge='outer'|'all'|None, outline='straight'|'round'|dict, dither, noise, group, inner_max)`；ramp 从浅到深，如 `['', '.', ':', '%', '@', '#', '#@']`，`'#@'` 表示 # 上再叠打 @；`group` 相同的角色之间不描边；`inner_max` 只在亮处给同角色的块与块之间描边
- 形状（子格遮罩）：`circle(col, row, 半径列数)`（自动按格子比例变圆）、`ellipse()`、`poly(点列)`、`shape(控制点)` 平滑闭合曲线、`rect()`、`blob()`
- 调子：`sphere_tone(col, row, r, light, amb)` 球（烟团）、`cylinder_tone(c0, c1, light, amb)` 竖圆柱（箭身）、`ramp_tone(p0, p1, t0, t1)` 线性渐变
- 作画：`fill(mask, role, tone)`；`erase(mask)` 挖回白纸；`stroke(点列, width, glyphs=None|'round'|单个字符, smooth)` 画线（单个字符如 `'='` 强制用它，平台、横梁用）；`billow([(col, row, r), ...], role, light, amb, shadow, glow=(col, row, r, 强度), lift=调子场)` 一团云：每团按球打光、给身后的云团投接触阴影，glow 是火焰从里面照亮，lift 给云底加暗
- 文字：`text(s, col, row, strike=2)` 原样打字（strike=2 两次叠打成粗体，opaque 让空格挖掉底下的画）、`text_v()` 竖排；`plot(col, row, w, h, xlim, ylim, [(xs, ys, 字符), ...], xticks, yticks)` 打印机绘图（I 纵轴、- 横轴、+ 刻度），返回把数据坐标换成格子坐标的函数（好在上面圈点）
- 打印：`compose()` 出字符网格（`listing(path)` 存成纯文本）；`print_rows(r0, r1)` 逐行击打（同一行所有叠打在走纸前打完）：同一个字符总是偏高或偏低一点（鼓的相位）、每列锤子力度不同（有一两列弱锤）、叠打的那一遍整行错开零点几像素、色带随作业变淡并沿宽度磨损、偶有色带偏低的行字头发虚、磨损的字模每次都缺同一块、墨往纸里洇、锤子压出极浅的凹痕
- 批注：`pen(点列, colour, width)` 圆珠笔（起落笔略积墨、快处变淡、在纸纹上断续）、`ring(x, y, rx, ry)` 顺手画的不闭合圈、`tick(x, y, size)` 打勾、`pen_text(s, x, y, size)` 手写字；这些用像素坐标
- 层次与动画：先 `fill`/`stroke`/`text` 摆完整张画，再 `compose()`，然后分几段 `print_rows` 并各 `stage(name)`，就是一行行打出来的动画；`save('x.jpg')` 默认 quality 88、4:4:4 色度
- 颜色常量 `INK`；`save(path, stages_dir)` 时按 1× 输出各阶段

**低多边形 `LowPoly`**：
- 思路：一个只用 numpy 写的软件光栅化器，照 1999 年代主机的做法画：小帧缓冲（默认 384×216）、顶点吸附到整像素、背面剔除、整个场景的三角形按平均深度排成一张表从远到近画（画家算法 / ordering table）、近平面裁剪；每个三角形一个颜色（平面着色），贴图仿射插值、不做透视校正，逐顶点雾；最后 15 位色加 4×4 有序抖动，最近邻放大。调用顺序不影响遮挡
- 构造：`LowPoly(W, H, scale=5, seed, record=True, zbuffer=False, near=0.6, far=260)`；世界坐标 X 右、Y 上、Z 向前，单位米；`zbuffer=True` 是 N64 式逐像素深度
- 相机：`camera(eye, target 或 yaw=, pitch=, fov, roll)`；`aim(世界点, at=(fx, fy))` 转动相机让这个点落在画面的指定比例位置（构图用）；`project(p)`、`ray(sx, sy)`
- 天与光：`sky(zenith, horizon, glow, bands)` 按仰角渐变、太阳周围暖光晕、可选细条云；`sun(screen=(fx, fy) 或 direction=)` 画太阳并定光照方向；`light(lift=度)` 着色光单独抬高；`ambient(sky, ground)` 半球环境光；`fog(near, far)` 逐顶点雾，颜色默认等于地平线
- 地形：`path([(x, z), ...])` 中心线，`along(path, s, u, y)` 取点、`heading(path, s)` 取方向；`canyon(path, step, height, width, wobble, strata, buried)` 沿中心线放样的峡谷（河床、沙岸、碎石坡、两级悬崖和台阶、崖顶、台地；岩壁按高度贴岩层，平面俯贴沙地 / 灌丛）；`river(path, half, ripple, spec)` 起伏小面的河；`mesa(x, z, r, h, base)` 方山；`arch(path, s, span, rise, base)` 天然石拱；`boulder(x, y, z, r)`；`tree(x, y, z, height)` 十字插片杜松（贴图 alpha 硬裁切）
- 物件：`ring(centre, facing, radius, tube)` 多面金环；`aircraft(pos, heading, roll, pitch, size, body, trim, canopy, spinner)` 约 230 个三角形的小特技飞机加半透明螺旋桨盘；`torus()`；`mesh(V, F, colour, uv, tex, lit, spec, shine, blend, alpha, two_sided, fog, bias, cutout, glow)` 任意网格：blend 用 'opaque' | 'half' | 'add' | 'sub' | 'quarter'（当年的四种半透明模式），bias 是排序偏置（负数后画），glow 把面往全亮拉（拾取物）
- 特效：`shadow(x, z, y, radius)` 正下方的圆斑影子（'sub' 混合）；`sparkle(p, size)` 加色四角星；`flare()` 屏幕空间镜头光晕（太阳被挡住就不画）
- 贴图：`texture('strata'|'ledge'|'sand'|'water'|'rock'|'juniper'|'spark')` 32–64 像素的程序贴图，最近邻取样
- HUD（帧缓冲像素坐标）：`text(s, x, y, scale, fill=颜色或自上而下的渐变列表, italic, anchor)` 5×7 点阵字（加粗、斜切、1 px 黑描边加投影）；`counter(label, value, x, y, icon, anchor)` 小标签加大号斜体数字；`icon('ring'|'plane'|'clock')`；`gauge(x, y, value, number, unit)` 阶梯速度条；`panel()` 半透明框；`minimap(x0, y0, x1, y1, path, s0, s1, rings, done, plane, heading, finish, title)` 转到机头朝上的赛道小地图
- 动画：`stage(name)`；`stage(name, wire=True)` 隐藏线线框；`stage(name, fog=False, textures=False)` 平面着色预览（每个面取中心那个纹素）
- 颜色常量 `GOLD WHITE BLACK HUD_YELLOW HUD_ORANGE HUD_RED HUD_GREEN HUD_CYAN`；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**喷漆模板涂鸦 `Stencil`**：
- 思路：一面真的墙，一张张真的卡纸模板，一罐喷漆。墙是反照率加高度图、左上方一个低太阳照亮；模板是卡纸上刻开的洞，被刻断的卡纸（O 的中间、手臂和身体之间、轮辐之间）会掉，所以要留「桥」，桥在漆上是一道道露墙的细缝；喷漆是罐子来回扫，每扫一道落下一个高斯锥，漆膜就是这些笔画的和；漆是一颗颗雾滴，厚的地方连成实色，薄的地方是散点，所以所有软边都是麻点而不是模糊；漆盖不进小孔、贴着墙面起伏、带缎面光泽；漆太厚的下边缘会往下流成滴痕
- 墙：`wall(colour, planks, ties, ground, damp, crack)` 木纹模板清水混凝土：一条条木板压出的色带和木纹（绕着树节走）、板头接缝、板缝挤出的断续水泥浆棱、对拉螺栓孔（锈铁头 / 灰浆堵头 / 空孔）、气泡孔、雨痕和锈水、返潮水线与泛碱、发丝裂缝；`pavement(colour)` 墙脚的沥青人行道（骨料、补缝沥青、口香糖渍、油渍、墙脚灰土和杂草）
- 旧痕迹：`buff(x0, y0, x1, y1, colour, roller, ragged)` 市政灰漆滚筒覆盖（竖向滚道、台阶状上下边、发干的两头、重叠处偏深，底下的东西透一点出来）；`freehand(..., wash=0.7)` 被高压水枪冲掉一半的旧签名
- 模板：`card(x0, y0, x1, y1, origin, scale, tape, material='manila'|'board')` 返回 `Card`，形状用设计单位（px = origin + scale × 点），返回局部遮罩，可以用 numpy 相加相减：
  - `poly(pts, smooth, facet)`（facet 是刀沿曲线一小段一小段切的抖动）、`capsule(p0, p1, r0, r1)`、`ellipse(c, rx, ry, rot)`、`ring(c, 外, 内)`、`stroke(pts, w0, w1)` 渐变宽度的带子
  - `text(s, x, y, size, font='stencil'|'slab'|'block', anchor, spacing, bridge)` 模板字：每个字腔自动上下各一座桥
  - `cut(mask)` 刻开；`keep(mask)` 留住卡纸（反白字、细节）；`bridge(p0, p1, width)` 手放一座桥；`bridges(width)` 自动找出所有会掉的孤岛、补最短的桥（大孤岛两座、方向相反）；`islands()` 还剩多少像素的卡纸会掉（0 才算刻好）
- 明暗分版：`shade_side(mask, light, depth, soft, wobble, seed)` 背光一侧 depth 像素宽的月牙，多层模板的灰版、黑版用它切；wobble 让边像手刻的
- 喷：`spray(card, colour, coats, cone, angle, misreg, at, rot, lift, mist, drips, drip_len, wet, linger, ghost)`。cone 是喷幅（像素）；misreg 是贴歪的随机误差（多版套色用约 2）；at / rot 把同一张小模板挪到别处、转个角度再喷（燕子、树叶、蝴蝶结）；lift 卡纸翘起量（软边和渗漆）；mist 外溢雾化；drips 滴痕多少，wet 起滴的漆膜厚度
- 徒手：`freehand(pts, colour, width, coats, speed, spits, drips, mist, wash)` 细喷嘴：线宽和浓淡跟着手速（speed 每个控制点一个系数，慢 = 重），起笔一团、停顿处滴、旁边几颗喷嘴吐出的大漆点
- `stage(name, card=c)` 快照里模板还贴在墙上（胶带、卡纸上积的漆、切口一侧亮一侧暗、卡纸投影），动图用；`save(path, stages_dir)` 默认 quality 88、4:4:4 色度
- 颜色常量 `BLACK WHITE GREY RED CONCRETE`；`HIDE` 各色遮盖力（白最差），`GLOSS` 光泽；字体 `stencil_font(style, size)` 找 DIN Condensed Bold / Impact、Rockwell、Arial Black，可用 `INKPAINT_FONT_STENCIL` 等指定

**刺绣徽章 `Patch`**：
- 思路：像绣花机那样绣：每块形状按自己的针向切成平行的行（扫描线），每行再切成针，所以形状的边缘就是一排针脚。每根线按圆柱打光，两头扎进布里（针孔是小凹坑），高光是各向异性的（Kajiya-Kay），同一种颜色换个针向亮度就不同，这正是「绣出来」而不是「印出来」的关键。徽章先是一块裁好的斜纹底布放在牛仔布上（有厚度、有投影），再绣、再包边，最后手缝上去
- 牛仔布：`denim(colour, weft, warp_px, pick_px, fade)` 3/1 右斜纹（经密纬疏，斜纹约 60°，露白纬点、竹节纱、磨白），2× 渲染；`seam(pts, thread, rows, stitch, gap, fold)` 双明线的折边缝，折棱磨白
- 底布：`blank(pts, 颜色)` 返回 `Blank`（`.pts` 轮廓、`.mask` 遮罩）；轮廓：`circle_pts(cx, cy, r)`、`arch_pts(cx, top, w, h, corner)` 拱形异形章、`rocker_pts(cx, cy, r0, r1, span, centre)` 弧形条章；遮罩：`circle()`、`ring()`、`poly(pts, smooth)`、`text_mask()`，用 `*`、`np.maximum`、`1 - m` 组合
- 填充：`fill(mask, 颜色, angle, kind='tatami'|'satin', pitch, length, stagger, maxlen)`：tatami 是大面积底色（短针约 15 px，每行错开 0.3 针）；satin 一行一根长线（字、雪顶、火焰、细长形），超过 maxlen 自动拆成交错的分段缎面；angle 是针向（度，逆时针，0 = 左右走）
- 沿路径：`column(pts, 颜色, width, closed)` 缎面柱，针和路径垂直（圆环分隔线、木柴、帐篷杆）；`run(pts, 颜色, stitch, gap, width, clip=)` 平针 / 刺子绣虚线 / 明线；`knot(x, y, 颜色, r)` 法式结（星点、火星）；`star(x, y, r, 颜色)` 四角缎面小星
- 包边：`merrow(blank, 颜色, width)` 锁边：斜着一圈圈绕过布边的圆绳，用于圆、椭圆、弧形条章；`satin_border(blank, 颜色, width)` 热切缎面边，用于其他异形轮廓
- 字：`text(s, x, y, size, 颜色)`、`arc_text(s, cx, cy, r, size, 颜色, centre=90, bottom=False)` 缎面字，每个字母斜着走针；bottom=True 沿下弧读、字头朝里
- 手缝：`whip(blank, 颜色, frm, to)` 卷边针，按轮廓长度的比例缝一段，返回最后一针的位置；`thread(pts, 颜色, lift)` 散落的缝线（有捻度，抬起越高影子越远）；`needle(eye, tip)` 躺在布上的钢针（先画线：线会从针眼里露出来）
- `stage(name)`、`save(path, stages_dir)`；`save('x.jpg')` 默认 quality 88、4:4:4 色度

**顺序**：都是先远后近、先大后小，文字最后叠加。水墨的雾要画在它该吞没的东西之后；水彩的叶梗要先画，并且只画在叶子外面。

## 三、毛病清单（都真实出现过）

**水墨**

| 问题 | 改法 |
|---|---|
| 后面的远山透过主峰 | 先远后近，`wash` 默认会遮挡身后 |
| 笔画像梯子或串珠 | 落笔间距跟笔毛挂钩（`bristle_stroke` 已处理） |
| 小路像头发丝，或是折线像裂缝 | 16 条左右，用 `spline` 平滑，只画在山体上，从雾里伸出来 |
| 皴擦像撒逗号 | 约 150 笔，长而顺坡，集中在阴面 |
| 山脊像卡通描边 | 山脊线用淡墨（0.3）加飞白，边缘靠水痕 |
| 松针像海胆 | 扇形松针，下面垫一团淡墨晕 |
| 主峰像锥子 | 左右坡宽度不同，加山肩和起伏 |
| 远山被挖出方块、断边生硬 | 用「从水线以下升起的山包」来留出水面，不要直接挖空一段 |

**水彩**

| 问题 | 改法 |
|---|---|
| 纸纹像砂纸或拉毛墙 | 纸纹受光强度约 0.3，纸纹要细 |
| 叶子中间一圈深色像靶心 | 第二层深色用湿画（soft 约 16）偏向一侧积色，不要同心 |
| 叶梗画到了叶面上 | 先画梗，用 `*(1 - 叶遮罩)` 限制只在叶外 |
| 颜色发脏 | 同一处罩染不超过三层；亮部留白或用 `lift` 提白 |
| 深色团块漂到树冠外，成了孤立的圆点 | 后几层罩染乘以第一层树冠遮罩（稍微扩一点），深色只积在冠内 |
| 树枝乱成一团 | 只画 3–5 根，从树干向上向外伸进树冠，长度按树冠大小算 |

**剪纸拼贴**

| 问题 | 改法 |
|---|---|
| 大面积蜡笔纹像满屏刮痕 | 大色块用 paper / kraft，蜡笔只用在点缀或小物件上 |
| 撕纸白边看不见 | 白边要宽出 5–8 像素（大半径模糊加低阈值），并且只出现在部分边缘上 |
| 画面顶边或左边多出一条阴影 | 阴影偏移不能用会首尾相接的循环平移，要用补零平移（已修） |
| 月亮画了光芒，像太阳 | 月亮用蜡笔光圈加几颗闪光，不要放射线 |
| 脸的五官太粗太凶 | 线宽约 r×0.035，腮红用 `glow` |
| 小鸟画成了一团 | 小鸟用两道细弧线（线宽约 2.6），不要用很短的粗笔 |
| 纸片被画面边缘切掉 | 云、气球这类主体要完整留在画面内，留出边距 |

**韩国彩铅**

| 问题 | 改法 |
|---|---|
| 颜色淡得几乎看不见 | 排线要够密（叠加后趋于饱和）；颗粒阈值不要卡太狠，用 pressure 控制能压进多少纸纹 |
| 奶油、白瓷等白色物体消失 | 用暖奶白色铺底，配淡紫灰或淡蓝灰阴影，再加一点白色高光 |

**日本动漫**

| 问题 | 改法 |
|---|---|
| 云是一个个正圆泡泡，明暗交界是斜直线 | 用不规则团块，数量多、大小不一；暗面用「团块减去偏移的自身」做成月牙形 |
| 人物腿太长 | 裙摆到膝盖附近，露出的腿约为身高的三分之一 |

**编辑风手绘**

| 问题 | 改法 |
|---|---|
| 色块死板，像电脑矢量图 | 每层专色都要有颗粒、浓淡不匀和几像素的套色错位 |
| 颜色太多太杂 | 4–5 种专色，靠叠印得到其他颜色（比如青叠黄出绿） |

**油画厚涂**

| 问题 | 改法 |
|---|---|
| 笔触像一根根塑料管、橡皮泥 | 凸起要克制：平顶鼓边的截面，高光约 0.1，打光范围约 0.8–1.18 |
| 笔触之间大量露底 | 铺底笔加密（density 约 2），宽笔铺满后再上细笔 |

**浮世绘**

| 问题 | 改法 |
|---|---|
| 云带半透明，透出后面的轮廓线 | 云带用不透明的色版（strength 超过 1，确保完全盖住） |
| 标题签和云带、主体撞在一起 | 标题签放在天空的空白处，其他元素给它让位 |

**像素风**

| 问题 | 改法 |
|---|---|
| 背景底部露出一条黑带 | 天空渐变和楼群都要铺到地面线，不留缝 |
| 光晕变成一大块方形点阵 | 光晕半径要小（约 20 像素）、强度约 0.4–0.5；霓虹光晕压扁一些 |

**黏土定格**

| 问题 | 改法 |
|---|---|
| 手指抹开的天空像揉皱的锡纸 | 指痕要宽（40–70 像素）、数量适中（200–350 笔）、脊线柔和低矮（`smear` 的 height 约 4）；先铺几种颜色再抹，拖色才看得出来 |
| 天空里出现笔直的矩形色块边 | 不可平铺的噪声不能取模循环平移，要在噪声图内部取窗口（已修） |
| 预先铺的色块边缘太硬，抹完还是一块一块 | 色块之间用 smoothstep 柔和过渡，再用手指抹 |
| 浪花像一排排一模一样的墙纸花纹 | 每朵浪的长短、高低、间距都随机；只排两三行，近大远小 |
| 鲸鱼像一条面包，尾鳍像两根分开的香肠 | 头要圆、身体向后收窄入水；尾鳍用一整片带中间缺口的翼形轮廓 |
| 前景水面在藏在下面的尾柄处鼓起一个包 | 部件默认顺着下面的高度铺；被遮住的部分别伸进水面太深，或在水线处用泡沫盖住 |

**蓝晒**

| 问题 | 改法 |
|---|---|
| 蕨叶像一串箭头或锯齿（鱼骨状） | 每片羽片做成一整片带圆齿边的叶片，加淡色小叶脉；不要一颗颗分开的小叶 |
| 小叶改成椭圆后又像含羞草 | 同上，蕨类的羽片是连在一起的 |
| 蒲公英绒毛几乎看不见 | 细丝不透明度约 0.3、lift 约 1；抬得太高会被半影模糊掉 |
| 刷涂边缘像毛刺、撕纸或动态模糊 | 按一笔笔横刷建模：每根刷毛在自己的位置干净利落地停住，干刷的断续用横向拉长的噪声（已修） |
| 茎穿过白色题字 | 题字放在留白处，茎的走向给题字让路 |
| 飘散的种子被涂布边缘裁掉，只剩一根线 | 小物件要完整落在涂布区域以内 |

**十字绣**

| 问题 | 改法 |
|---|---|
| 斜向的短线（太阳光芒）被吸附成一串 L 形台阶 | 短斜线就绣一针，从孔到孔（`step` 设大） |
| 半针叠在十字绣上，像贴了一层纹理 | 真实绣法不会这样叠：亮部直接换浅一号的线绣十字 |
| 烟囱被屋顶整个盖住、烟线穿过标题 | 先算好屋顶轮廓再定烟囱高度；烟用半针小烟团，往留白处飘 |
| 布面格子太黑，像方格纸 | 布孔暗度约 0.34，布块起伏约 0.065 |
| 花朵和松树重叠 | 摆放前按格子算好每样东西占的列 |

**复古仪器面板**

| 问题 | 改法 |
|---|---|
| 喇叭布上的金丝像一排点点，看着像冲孔板 | 金丝纬线要长浮（压过三根经线再钻下一根），闪光沿线缓慢变化 |
| 刻度单位和最后一个数字挤在一起 | 单位放到刻度末端外侧，或者直接写完整数值（530…1600 kHz） |
| 浅色字印在浅色喇叭布上看不见 | 丝印颜色要和底材拉开明度 |
| 一大片喇叭布太平、太假 | 布是半透明的：把后面喇叭的圆形暗影淡淡透出来 |

**贴纸拼贴 · 小票**

| 问题 | 改法 |
|---|---|
| 面包只有一道长割口，像红薯或叶脉 | 三道斜向交叠的割口：浅色裂口加深色翘边，再撒面粉 |
| 花束的花用同心圆画，像靶心或棒棒糖 | 侧面郁金香：两片带尖的外瓣，前面一片浅色瓣 |
| 印章小字压在内圈线上 | 中心字上移，分隔线放在 +0.16r，小字写短，全部收在内圈以内 |
| 小票字太黑，像打字机不像热敏纸 | 灰色油墨 #4f525a、浓度约 0.8、边缘微糊，加断针竖纹和走纸浓淡 |
| 小票右半边整条发灰 | 横向卷曲压到很小，只让长边两端翘起 |
| 纸边的贴地阴影像描了一圈黑线 | 纸张接触阴影降到约 0.26 |
| 印章盖在条码上看不清 | 盖在金额和星号一带的稀疏处，只压一点字，更像真的 |
| 印章墨色太匀，像电脑填色 | 加压力倾斜、大块浓淡和漏印小坑 |
| 标签上的字溢出圆标 | 文字改短、字号调小 |
| 右下角空出一大块 | 加摊位号圆贴纸，第二个吊牌用长绳垂下来 |

**实验笔记本 · 贴纸**

| 问题 | 改法 |
|---|---|
| 铅笔线像干净的矢量墨线：细、匀、太黑 | 手绘线宽约 3 px、抖动约 1.6；石墨只挂在纸纹凸起上，重压也保留一点颗粒 |
| 轻压的排线、表格横线断成一串点点 | 覆盖率保留约四成连续的浅灰，颗粒只调制剩下的部分（`_graphite` 已处理） |
| 折线图数据点画成小圆圈，像字母 o、c | 用压实的小铅笔点（很小的螺旋，pressure 1） |
| 曲线一笔画成，太完美 | 分两笔画，接头处稍错开、稍重叠 |
| 标注字压在曲线上，单位和刻度撞在一起 | 标注放到曲线下方空白处，用铅笔小箭头指过去；单位放到轴端上方 |
| 贴纸孤零零浮在图下面，看不出指什么 | 从最佳点画铅笔虚线到横轴，贴纸贴在同一个 x 上 |
| 标签机胶带两端剪成 V 形缺口，像彩带横幅 | 两端直剪、略斜、小圆角 |
| 咖啡渍像肥皂泡或透镜 | 外缘一圈细而深的水痕线，内部几乎均匀的淡色；圈有断口、一侧更深 |
| 红笔箭头被后贴的便利贴盖住 | 箭头停在便利贴边缘外，或先贴便利贴再画箭头 |
| 标题上的荧光笔起笔压到了前一个字 | 起点按字宽算，落在目标字的左边缘 |

**黑板板书**

| 问题 | 改法 |
|---|---|
| 粉笔线像干净的矢量线：满压几乎实心、边缘光滑 | 满压也要留约 15% 的坑点（阈值 0.98 − 0.86 × 压力）；笔尖接触面按线宽的 0.26 倍模糊，边缘才会毛、才会断 |
| 中文（黑体）比 Helvetica Bold 细一截；加粗后 30 px 的复杂字糊成一团 | 中文按字号加粗，小字加粗减弱；40 px 以下自动加压、减轻颗粒和边缘扭曲（已处理） |
| 字体的粗体 ∝ 被粉笔加粗后闭合，看着像 ∞ | 用 `propto()` 手写一笔：双纽线的左瓣加两条向右的尾巴 |
| 大气层用侧锋铺色，成了一整块发闷的矩形，压住上面的波浪和标注 | 压力约 0.3、strength 约 0.6，用 `weight` 做渐变（近地面浓、往上淡），左右两端长距离渐隐 |
| 上节课的残影被后来的大擦痕又擦没了，或者压在新板书下面影响阅读 | 残影 keep 取 0.26–0.34，大擦痕 strength 不超过 0.6；残影放在空白处（上沿、角落、标题和图之间） |
| 动图调色板只取最后一帧，满屏绿色吃掉色位，粉彩粉笔、光谱条发灰 | 调色板用加权像素样本做中值切分（彩色像素 ×5、亮色 ×2），所有帧仍共用这一张 |

**赛博朋克**

| 问题 | 改法 |
|---|---|
| 倒影按一条地平线整体翻转，位置全错；被近处天桥挡住的远景在倒影里成了黑洞 | 每个物体按自己的着地行（mirror row）翻转，最近者优先；被挡住的空洞用对应行的雾色填 |
| 一楼店面发光太亮太大，近处成了过曝的纯色墙，货物画成色块像霉斑或柱状图 | 店内亮度 0.2–0.45，从天花板往下衰减、两侧变暗，加货架侧影和人影；最近的街区多放卷帘门和自动售货机 |
| 雨丝统一提亮成满屏灰帘，溅落圈太大像气泡 | 每根雨丝按周围光照上色，只在霓虹附近看得见；溅落圈半径 3–11 厘米，只在水洼里亮 |
| 蒸汽用背后的暗画面照亮，完全看不见 | 蒸汽按光源外溢光照明（像一块浅色表面），再加前向散射 |
| 光轨沿街飞，全都汇向灭点，像激光或钢丝 | 让飞车横穿街道：从一侧墙后出现，拱形掠过，消失在另一侧墙后；加频闪点 |
| 全息水母的 1 像素线被雾和扫描线吃掉；C 形生殖腺像数字「93」，后排两个像一双眼睛（成了脸） | 线宽至少 2 像素；生殖腺放在伞内的水平面上，侧视压成一条柔和的粉带；副标用 Light 字重，撕裂切片别落在字上 |

**卡通手绘**

| 问题 | 改法 |
|---|---|
| 窗外的太阳画到了墙上 | 窗里的东西都乘玻璃遮罩；被挡住的轮廓只画露出来的那段弧（`ellipse_pts` 给 a0/a1） |
| 手臂从头顶直直伸出、末端一个圆球，像触角或棒棒糖 | 肩膀放在身体侧面中部，先画手臂再画身体；bend 的正负让手肘朝外弯；手套加拇指、袖口和两道指缝 |
| 两个角色挨得太近，一个的手套落到另一个脸上 | 只画外侧那只手臂，内侧的藏在身后 |
| 烤色蜡笔涂在面包中间，像脸上的脏污 | 烤色只涂面包芯内缘一圈（轮廓遮罩减去内缩的轮廓），脸所在的中间保持干净 |
| 纸纹太粗，色块上像砂纸 | 纸纹受光约 0.026，颜料盖住的地方纹理减半（已处理） |
| 闪光星像菱形 | 用指数约 3 的星形线，竖向拉长（已处理） |
| 白字写在米色纸上看不见；白云、手套、烟团都是白色小圆团，挤在一起分不清 | 浅色字只写在深色块上；白色圆团之间拉开距离，背景里不放白云 |
| 飞溅的碎屑落到脸上 | `crumbs(..., avoid=角色遮罩)` |
| 动图 2.3 MB：铅笔稿每阶段换强度又跟着抖，网点和蜡笔也跟着抖，每次叠化都整片重编码 | 只抖墨线，颜色和铅笔稿留在纸上不动；铅笔稿强度在勾线之后固定；阴影和质感合成一个阶段（1.9 MB） |
| 黄油的嘴压在底边线上；滴落太小，水洼像一根黄条 | 脸按物件正面的高度缩放、上移；滴落画成从前沿挂下来连到水洼的一道，最后画，压在轮廓线上 |

**等轴 2.5D**

| 问题 | 改法 |
|---|---|
| 白墙整面发灰，比同一面墙上方的山墙暗一截 | 高度图 AO 会把楼自己的高度算进墙面；侧面改为沿法线（及左右 40°）看地平线，只算挡在前面的东西（已处理） |
| 屋檐、树冠被当成实心柱子，墙顶一圈发黑 | 顶视图同时记录最高那根「柱子」的顶和底：相接的实体合并，悬空的单算，只挡它实际覆盖的那段仰角；檐下不算墙角折痕（已处理） |
| 平顶楼墙上出现一条锯齿状灰带 | 柱子的顶 / 底不能跨边插值：细檐口一插值就在墙边造出一块假悬空板；改最近邻采样（已处理） |
| 长投影的半影满是颗粒 | PCSS 每像素旋转采样之后，再做一遍按深度保边的可分离模糊（已处理） |
| 海面上的短浪线竖着立起来 | 等轴视角里世界 (1, 1) 是屏幕竖直方向；浪线沿世界 y − x 走才是屏幕水平（已处理） |
| 砖缝像棕色勾缝，沙滩缝像一根根圆木 | 草地砖侧面保持草色，只让台地露出土层；缝宽约 0.028 格 |
| 岛占满底座，沙滩一圈像棋盘，看不出是岛 | 屏幕左下、右下两条前边留 1.5–2 格海面；沙滩只放在部分岸边 |
| 卫星天线正对镜头，像棒棒糖或路牌 | 朝向和视线错开（yaw 约 125°、仰约 50°）；反射面中间暗、边缘一圈亮（已处理） |
| 数据卡字太小，折线图压到单位上 | 卡片约 2.9 × 1.65 格，大数字约 0.7 格高；折线图从「数值 + 单位」之后开始（已处理） |
| 引线横穿房顶，画面乱 | 卡片围着各自仪器摆，用 `unproject()` 按屏幕位置定点，引线短、不跨主体 |
| 草地上散落的小花像彩色糖珠 | 花开在灌木上：`tree(kind='bush', flowers=…)` |

**单线画**

| 问题 | 改法 |
|---|---|
| 纸飞机画成小三角，像风筝或三角旗 | 用 3/4 俯视的飞镖形：近翼大、远翼透视缩小、中间一道折痕；笔从尾部缺口进、从机头出，四个角保持尖 |
| 航迹从谷底地面起飞又落回地面，看不出从哪飞到哪 | 线从 A 屋的窗里穿墙飞出，从机头穿墙飞进 B 屋的窗；两屋之间不画地面 |
| 翻圈放在爬升段，像挂在线上的气球或套索 | 翻圈放在轨迹顶部、路径接近水平处，`curl(..., aspect≈1.2)` 让圈更圆 |
| 航迹和房子一样粗、从地面附近起落，整条读成山丘或山脉轮廓 | 航迹段 `pressure=[(s0, s1, 0.62)]` 用轻手画细，从窗口直接上扬，不先下沉 |
| 轨迹末端急转直下，在飞机尾部勾出钩子，还和后翼边贴成细长条 | 把飞机尾部缺口的坐标作为轨迹最后一个控制点，入射角放缓到约 35° |
| 窗户、山肩这类要从里面够到的形状一笔连不过去；原路回来的短线头是钝圆头 | 用 `retrace()` 原路去再原路回（成图看不见）；原路折返处自动提笔收尖（已处理） |
| 树冠贴着屋檐，两样东西粘成一团 | 物件之间留出间隙 |
| 动图里深蓝渐变出现一圈圈色带，唯一的琥珀色窗被量化成米黄 | 调色板拆开：空底色 110 色、画出来的东西 145 色（饱和像素 ×6）；量化前加固定的 4×4 Bayer 抖动，每帧相同 |

**柔光 3D**

| 问题 | 改法 |
|---|---|
| 掉下去的球悬在字上方，字面上有莫名的暗斑 | AO、阴影、落球这类查询在包围盒外用了盒子距离，球停在了看不见的盒子上；字形距离网格覆盖的范围内一律用精确距离（已修） |
| 字脚一圈球发黑，字的下半侧有黑带 | 球海距离场只查 2×2 格、封顶半格，清空的格子旁边 AO 以为贴着球；改查 3×3 格、封顶一整格，AO 半径 0.3、强度 1.25、留 0.1 的底（已修） |
| 字从球海冒出来，脚下一圈空槽露出黑地板，像抠图 | 被挤开的球不删，按「落进最近的空窝、层层叠、要有三点支撑」堆到字脚：`part(pile=10, pile_top=0.3)` |
| 字埋得太深，s 只露出上半截像 c，整词读成 rice | s、e 用 bob 单独抬高，让它的下半弯露出来；part() 加 pile_top=0.3，只堆一层，堆起的球不能高过字母下半部 |
| 阴影里的薄荷球发青灰、发脏 | 淡紫天光乘薄荷色会发灰：阴影加按材质自身色调的次表面补光，天光调强、主光调弱 |
| 球排成直行一直通到远方，像条纹墙纸 | 整个场景转 30°，行列斜着走 |
| 清晰的字边有锯齿，高光一节一节 | 成片 1.5 倍超采样再 Lanczos 缩小；字形距离场模糊 2 像素，法线差分步长 2.5 个格（已处理） |
| 上三分之一一片惨白，远处和背景之间有一道硬地平线 | 雾色等于背景地平线色，雾距约 42；镜头稍抬，露出天空渐变 |
| 动图 3.4 MB，小黄球被量化成一块平色片 | 景深跟相机一起先设好（每个阶段都柔），曝光并进灯光强度，主光和轮廓光合成一个阶段；调色板样本里彩色像素 ×5 |

**形变动画**

| 问题 | 改法 |
|---|---|
| 起点、绕向没对齐，中间帧塌成一条条碎片 | 先 `normalise`（同样点数、顺时针、从正上方起），再 `align`（FFT 互相关找最佳起点）；一串关键帧用 `chain` 依次对齐 |
| 每段 5 个残影、关键帧又太大，雪花和云的花边残影叠成一片噪点 | 关键帧约占面板宽的六成；每段只画 3 个残影，中间那帧填色约 0.42，两侧只留细线和约 0.14 的淡填色 |
| 运动轨迹画成圆点，和中间帧上的对应点混在一起，看着像轨迹绕了个圈 | 轨迹用虚线（`trail(dash=)`），圆点只用来标对应点，图例里分开写 |
| 速度线等长等距，像梯子，落在河边还被当成水流线 | 海报里不画速度线，靠挤压拉伸和残影间距表现速度 |
| 纸纹把奶白色的云也盖成了砂纸 | 形状保持纯平：纸纹只加在露出的纸面上（`tooth` 遮罩），面板和形状只有极轻的印刷颗粒 |
| 闭合样条在直角处过冲，海浪底角鼓出一个包；太阳的细光芒是断开的小棍 | 只对曲线部分做样条，底边用直线接；光芒用楔形加圆头，和圆盘连成一体再描外轮廓 |
| 后一段的残影线压在前一个关键帧上；标签重复画了两遍，颜色变深 | 画完残影后重画前一个关键帧（只重画形状内的细节）；文字和形状外的点缀只画一次 |
| 「↺」在所用中文黑体里没有字形，显示成方框 | 循环箭头用 `outline` 画圆弧再加 `chevron`，方向取圆弧终点的切线 |

**报刊拼贴**

| 问题 | 改法 |
|---|---|
| 齿轮像一块灰饼：齿面和背景一样亮，窗口被投影压灰，齿比网点还细 | 齿面反照率约 0.56、metal 约 0.3，加车床纹的「领结」反光；抬起高度约 8，背景投影 0.35；齿距至少约 4 个网点（r=108 用 36 齿），剪边约 9 px |
| 发条画成一圈圈同心圆，像靶子 | 圈数 4–5，`flare` 约 1.6：里圈密、外圈松，才看得出是螺旋 |
| 打字机字体没有「→」，出现豆腐块 | 逐字检查字形，缺字自动换中文黑体（已处理） |
| 问号纸片压住主体表盘的数字 | 用上一个字的 Frame 算位置，整排标题缩小；主体整体右移给标题让位 |
| 红章盖在密密的报纸字上认不出 | 章盖在牛皮纸的空处 |
| 邮戳环形小字断成「CUR:OSTI」 | 环形字至少 18 px；橡皮漏印改成部分漏墨（0.3 + 0.7 × keep），细笔画不断（已处理） |
| 剪下的照片白边处处一样宽，像模切贴纸 | 白边宽度沿周长慢慢变宽变窄（`wander` 约 0.45），但永远不剪进物体（已处理） |
| 散落的零件看不出是从闹钟里飞出来的 | 先从缺口画几条虚线弧再贴零件，起点错开别汇成尖点；离缺口最近放一颗螺丝 |
| 带邻字的报纸剪字，邻字太大太黑，抢了主字 | 邻字字号约 0.075 倍、浓度 0.62，主字周围留一圈空 |
| 报纸透印太重，镜像标题像渲染错误 | 透印浓度约 0.045，模糊 1.4 px |
| 牛皮纸纤维太长太黑，像裂纹或头发 | 纤维 4–20 px，深色浓度 0.2 |
| 动图调色板被牛皮纸和报纸占满，芥末黄纸片变成土黄 | 调色板取样时高饱和像素算 5 倍（色差 24 → 2.7 / 255） |

**弥散玻璃**

| 问题 | 改法 |
|---|---|
| 前面的卡片压住后面卡片的字（「周三」「60%」被切掉一半） | 卡片只在对方的内边距里重叠（不超过内边距），文字离重叠区远一点 |
| 列表最后一行和底部按钮撞在一起 | 先按行距（约 84）算好列表总高，按钮从卡片底边往上放，不够就加高卡片 |
| 玻璃太「奶」，像磨砂塑料，后面的东西透不出来 | 白纱 tint 约 0.24（近光源一侧厚、另一侧薄），saturate 约 1.5；背景色团之间要有足够的色相差 |
| 小球刚好顶在卡片边上，像放在卡片上面 | 让小球三到四成真正压在玻璃后面，模糊的那一半才读得出「透过玻璃」；小球也别和卡片边相切 |
| 背景的色团和光带几乎全被卡片挡住 | 光带穿过卡片之间的空隙走，色团饱和度提一点 |
| 折线图的面积填充在末端成了一团紫雾 | 填充 alpha 约 0.16，两端各 22 px 渐隐（已处理） |
| 柱状图柱子太细，满高的空槽像幽灵柱，「一」看着像减号 | 柱宽取间距的一半，空槽 alpha 0.1；横轴用日期加「今天」 |
| 动图调色板被浅色背景占满，渐变控件量化成灰，小球出现等高线色带 | 调色板样本给饱和像素加权（×6 / ×3，暗色 ×4），每帧叠同一张 4×4 Bayer 抖动（约 ±2.4 级）：逐帧不变，「和上一帧相同」的透明差分照样有效 |

**包豪斯几何**

| 问题 | 改法 |
|---|---|
| 颗粒太重（约一成面积露纸），色块像砂纸、字像磨旧的橡皮章 | 露纸坑点控制在约 2%，只出现在墨膜偏薄的刮板条纹里；黑墨最少（GRAIN 0.4） |
| 坑点成团，像均匀撒了一层雪 | 纸齿用像素级白噪声加少量团块；墨膜另加约 ±2.5% 的浓淡微纹理，不全靠露白点 |
| 方块直角被磨圆 | 版边只做 3×3 轻模糊再加噪声阈值，不用大半径模糊 |
| 页边小字、铅笔版号、色标条压在裁切线上 | 左起 x≈86、右止 x≈1834，色标条末端离裁切线至少 40 px |
| 叠印色标全显示成上层颜色 | 丝网墨基本不透明，叠印色标默认关（`overprints=False`） |
| 黑色标注印在蓝色上看不清 | 深色块上的标注从该色版挖空（`knock=`），露出纸色 |
| 「60 °」度数符号离得太远 | 度数符号自动收紧 0.1 em（`_KERN`） |
| 标题和右上角讲座信息撞在一起 | 先按 120 px 模数排好每栏宽度，信息行写短 |

**复古 Synthwave**

| 问题 | 改法 |
|---|---|
| 太阳被泛光冲成一团白，横条切口被光晕填平 | 太阳底色先压到约 0.72、发光 level 约 0.4，让泛光提回来；切口厚度从条距的 0.2 递增到 0.7 |
| 横穿太阳的细条云像多出来的切口 | 有切口的太阳前面不加 `streaks`，细条云只放在太阳外 |
| 海面倒影是一团糊的圆，像水下还有一个太阳 | 按世界深度把水面切成横带，每带横移、以太阳所在列为中心随机拉伸或压缩（越近越乱），再用短划调制；光源的倒影比天空强约 2.4 倍 |
| 远处网格变成一大片平的橘色雾带 | 雾距 150 m，雾色压暗、偏品红；网格线按屏幕像素距离算覆盖，格子小于几个像素就换成平均值，不出摩尔纹 |
| 录像带噪点像画布纹理，线条满屏抖动打折 | 噪点约 0.014、横向拉长；逐行抖动约 0.35 像素，只留一条跟踪噪带和底部磁头噪声 |
| 霓虹手写字白芯太粗，整句像白字；随机断管像渲染错误 | 白芯只取笔画最中间，core 约 0.5；断管默认不加 |
| 棕榈冠像冷杉，改了又像平顶伞 | 叶柄仰角从陡到平均匀分配，加两片下垂枯叶；小叶在 3D 里朝叶尖前扫、向两侧展开再下垂后投影，不要一律竖直挂下 |
| 城市摆在线框山前面，暗对暗，高楼像幽灵 | 城市放在灭点旁、背靠落日余晖，山脉从城市右边才开始 |
| 小岛挡住太阳正下方，吃掉最亮的一段倒影 | 小岛只和太阳左缘略微相交 |
| 阶段快照里地平线下是整块橘色，太阳下半截露在地上 | `sky()` 先铺一层没点亮的暗色地面；太阳在地平线处截断 |

**拼豆**

| 问题 | 改法 |
|---|---|
| 钉板四周出现一整块深灰方框 | 豆子高度只写在豆子覆盖处（其余设 -1e3），别把整个窗口抬到板面高度 |
| 熨过的豆还是一颗颗分开的甜甜圈，和没熨的差不多 | melt 同时控制：外半径 +22%、smooth-min 融合宽度增到 0.55 倍珠距、孔缩 74%、高度降 40%，外沿和孔口分开倒圆；0.4 是半熔（孔在、珠粘、留菱形缝），0.7 是成品 |
| 熨平的杯垫像一块块六角螺母，表面像糖霜 | 接缝沟只在半熔时有（×(1 − m/0.7)²），顶面只留 5% 的枕形起伏，熨烫纸细纹 0.08 px |
| 收纳盒里的豆堆成一根根塔 | 散豆落在下面的东西上，但限高约一层豆（`cap`）；每格约 20 颗，按抖动网格铺开 |
| 镊子像两根筷子、像白纸条 | 两腿成 V 形，尾部合拢、尖端张开一颗豆宽，腿宽 1.5→4.9 px；钢色偏暗，靠拉丝纹和窄的灯箱反射显出金属；悬空层单独投影 |
| 白豆侧壁出现竖条纹、钟乳石状锯齿 | 侧壁的 AO 和阴影改从平滑图上、在墙脚和墙顶内侧取样；墙顶取最近几行的最大高度；太陡的抗锯齿斜坡按侧壁着色 |
| 熨烫纸（缓坡）上出现发丝状细线 | 朝镜头的缓坡会把一行拉成约 1.1 屏幕行，超过 1.5 行才算侧壁 |
| 高光要么看不见，要么每颗豆一圈白光环 | 用灯箱反射：镜面方向落在主光方向 8° 内（越粗糙越宽）才亮，得到左上沿和孔内远侧唇口两道弧；菲涅尔权重压到 0.08 |
| 熨烫纸盖住标签，字变半透明 | 后放的会盖住先放的，用 `on_top()` 把标签、杯垫提到最上层 |
| 图例铅笔勾挤到前一栏数量上；深绿、叶绿都印成 G | 勾直接打在豆子图标上；符号原样印，不转大写 |

**岩画（凿刻砂岩）**

| 问题 | 改法 |
|---|---|
| 沙漠漆像木纹、像一整幅竖条窗帘 | 不用全幅竖条噪声；漆膜近乎均匀（0.86 ± 0.09），流痕是一条条独立的对象：多从顶部起、往下变窄变淡、略左右漂移，边缘 ±2.5 px |
| 流痕像条形码（硬顶的黑色矩形） | 流痕顶端 50 px 渐入、长度 30%–100% 段渐隐，不从硬边矩形源往下涂 |
| 流痕糊成一团团烟，挂在羊身下面像投影 | 不要整体 bicubic 放大成软团；只在横向留 ±2.5 px 的过渡，纵向才平滑 |
| 流痕像一根根火柴棍 / 芦苇帘 | 宽度取对数正态（中位约 18 px）、约 110 条、只把漆加厚 0.2、锰色 0.6；再加约 26 条更宽的浅色流痕（漆被水流冲薄） |
| 薄漆的「窗口」成了迷彩斑块 | 不用块状窗口，浅色也做成竖向流痕 |
| 凿点太稀，图形像撒了一层粉笔末 | 凹坑数 ≈ 3.4 × 图形面积 / 单坑面积；坑深相加后饱和（dmax ≈ 2.9 px），内部打满只留小暗缝，轮廓在一个坑的尺度上毛糙 |
| 羊身细长像腊肠，整群首尾相连成一条带 | 身体加深（-0.20 到 0.15 个身长）、颈粗；大羊一排、母羊小羊一排错开，彼此留空 |
| 剥落像贴上去的光滑椭圆，四周一圈黑 | 轮廓拆成 14–40 px 的小段、每段向内弯成小贝壳弧；AO 减弱（深度 2.4 / 7 / 22）；疤面颗粒减半、鲜橙色带铁质色带，唇口一圈浅色风化皮 |
| 地衣像绿色颜料点、像一枚枚硬币 | 低饱和橄榄色，椭圆加不规则叶状边、龟裂纹、小黑子实体、周围卫星小点，alpha 约 0.7 |
| 太阳螺旋中心成了「f」，光芒离螺旋太远像飘着 | 螺旋从 1.4 rad、10% 半径起步，中心只点一个小点；光芒从最外圈外 1.7 倍线宽处开始 |
| 蹄印像等号或乱点 | 两瓣从蹄跟到蹄尖向中线收拢成心形（尺寸 ≥ 30 px，凿点 size 0.66）；第一枚离羊蹄远一点 |
| 小孩手印糊成一团 | 手印 ≥ 约 95 px，凿点 size 0.62、density 1.2，手指才分得开 |
| 光秃砂岩像一块木板（层理像木纹、小凹坑像钉眼） | 层理振幅减半且时有时无，石色只随层理变 1–3%；凹坑改成 7–26 px 的浅碟 |
| 画面顶边、左边多出一条黑带 | 投影步进前用边缘复制把高度图 pad 一圈（越界补 0 会被当成一堵墙投下影子） |
| 岩檐只像一道裂缝 | 台阶 34 px 才有一条看得见的檐下投影；檐口折线 + 轻微倒圆 |
| 新旧凿痕只有「全新」和「鬼影」两档 | 加中间档 age 0.3（新月、计日刻痕、掷矛手）：0 新凿、0.3 几百年、0.6–0.7 几乎被漆盖回 |
| 动图里橄榄绿地衣被量化成灰 | 给偏绿像素单独留 6 个调色板位，「和上一帧相同」的占位色用品红 |

**古埃及墓室壁画**

| 问题 | 改法 |
|---|---|
| 弯腰的人还是正面宽肩，后肩翘到头顶上，横过胸前的手臂像一条绶带 | 按前倾角把肩宽往侧面收（前倾 32° 时只剩约 15%），两只手臂都从胸前出发；坐姿直接给 `turn` |
| 蹲坐的书吏把脚转 180° 后脚底朝天，两臂缠在一起 | 压在身下的脚左右镜像（`mb=True`，脚尖朝后），肘部 IK 一律朝下弯，`turn=0.45` 收窄躯干 |
| 灰泥脱落像贴上去的褐色石片，带一圈发亮的白边 | 做成真的高度图：洞深 8 px，低角度光沿高度图投影（左上内壁一道影），洞底近壁处加环境遮蔽；石膏白边只留 2–4 px 且断断续续，洞口四周的颜料按台阶剥落 |
| 底色把人物里的红稿整个盖掉，剥落处只露出黄底 | 底色绕开要上色的形状刷（`ground(around=True)`）：动画里红稿一直留到上色那一步；人物上的剥落露出灰泥上的红格和红稿（`age(zones=...)` 可以指定几处） |
| 干活的人都戴宽项圈，分不出主仆 | 只有总管和书吏戴项圈；劳工赤膊，有的剃短发（`wig='cap'`，露耳朵） |
| 象形数字 ∩‖ 读成「ΛI」：一竖藏在 ∩ 的腿后面 | 每个 ∩ 之后让 0.78 em，竖笔间距 0.3 em，字号 46 px 以上 |
| 粮袋正中那道褶像一张笑脸 | 褶线挪到袋子一侧，竖着走 |
| 无花果树冠是一格格圆点，像波点布 | 尖叶按行排、隔行错开、下一行压住上一行（像鳞片），深浅绿隔行；水囊挂在一根截断的枝上 |
| 锄地的人像在推棍子，量斗像一本书 | 锄头画成倒 V：双手握柄，柄顶绑宽木刃斜插进土，中间一道绳；量斗是上宽下窄的木桶，口上堆着粮，倾斜着倒出一股粮粒 |
| 扛东西的人手捂额头，袋子盖住了脸 | 后手举起扶住，货物压在后肩、在头后面（z 夹在躯干和举起的手臂之间）；部件细节的 z 偏移只给 +0.002，否则筐的编织纹会跳到手臂上面 |
| 埃及蓝像一层蠕虫状噪点 | 蓝、绿两色改用稀疏的亮晶粒加暗颗粒（`T_cryst`），通用颗粒压到 0.05 |
| 底色的斜向刷痕整面平铺，像雨丝 | 两个方向、按大块噪声时有时无，幅度 0.012–0.015 |
| 潮痕像一条钢笔线横穿人物 | 宽约 0.012 H 的柔和带，上沿稍清楚，往下逐渐泛褐 |
| 动图 3.7 MB（满墙颗粒让每次叠化都改掉一半像素） | 关键帧先做 1 px 高斯平滑；量化时新颜色和上一帧已显示的颜色相差不超过 10 级就沿用上一帧的索引（透明差分照样有效，自检仍逐帧比对）→ 1.85 MB |

**罗马马赛克**

| 问题 | 改法 |
|---|---|
| 石子像一个个鼓起的枕头，整幅像碎石路 | 地面是打磨过的：石面只高 1.5–2 px、倒角半径约 1.7 px，漫反射 0.45 + 0.55；切石抖动 4.5%、缺角 20%、转角 ±1.6° |
| 灰色的鱼身里混进淡蓝、粉色石子 | 取石在「亮度 + 红绿 + 黄蓝」对立色空间里比，色度权重 2.6，抖动主要加在亮度上（已处理） |
| 轮廓那一排又宽又长（约 13 px 深而不是 8 px），第二排轮廓铺不出来 | 判断「里面还有没有下一排」用的脊线最大值滤波半径小于一排间距，每排都以为自己是最后一排、往里加宽：半径取 2 × 排距（已修） |
| 波浪纹边框整圈不见了，只剩白排 | 局部坐标的周期被带高乘了两次，波浪画到几千像素外：周期 / (1.5 × 带高) 再乘带高 |
| 边框的浪是一条条细 S 线，像卷草不像浪 | 浪身是从黑框边长出来的实心块，浪尖沿一条渐细的粗线卷回去，中间留一个白「眼」 |
| 收起挂在帆桁上的帆像一把伞 | 改成从帆桁垂下、向一侧鼓起的方帆，竖向缩帆索用浅色石子 |
| 小海鸥外面套两圈背景光环，像装在泡泡里 | 所有东西先一圈光环；第二圈只给大图形（船、灯塔、铭牌、网、章鱼），量距离时把第一圈也算进去 |
| 网里的鱼被网线切成碎块，看不出是鱼 | 网里的鱼先铺（眼、鳃线、轮廓、填满），网线后铺，碰到鱼自动断开 |
| 被偷的那条鱼太小、贴着网，看不出章鱼在偷 | 鱼放大到约 150 px、拖到网外，章鱼最长的那条腕绕住鱼尾 |
| 天空里的脱落像一个灰色加号 | 脱落放在边框和海里、靠着裂缝；旧灰浆床压暗偏暖，留下石子方坑 |
| 铭牌燕尾耳尖上散着红色碎屑，小字像虚线 | 耳朵填完只补大于半块的洞（`tuck(small=0.55)`）；字的石子边长取字高 / 5.6，不小于 5.6 px |
| 动图 3.2 MB：最后一次叠化整幅都在变 | 阶段快照和收尾帧都按 `stage_ss` 渲染（分辨率一致）；积灰只成片出现、不整幅压暗；和屏上颜色差 ≤ 10/255 的像素按「没变」透明 → 1.57 MB |
| 动图里金色火焰、光芒变成粉橙色 | 调色板分两份：饱和像素按 12 个色相区等量抽样，单独中值切分 48 色，其余 207 色 |
| 峰值内存 2.6 GB | 2× 渲染按 96 行条带做，起稿、噪声、裂缝图留在 1× 逐条放大；paint / shade / sinopia 只在遮罩外接框里算 → 1.35 GB |

**彩色玻璃花窗**

| 问题 | 改法 |
|---|---|
| 铅条像半透明的灰色铅笔线 | 光晕叠到铅条上只留约两成，铅的颜色压到 #2c2d31 左右（已处理） |
| 同一道条纹横穿相邻几块玻璃，像盖了一层滤镜 | 每块玻璃取自整张料的不同位置：条纹按块加随机相位，方向也按块随机（已处理） |
| 树冠每个圆团单独一块料，铅条围出一圈圈圆，像肥皂泡、像葡萄 | 整个树冠用一次 `glass()`（多种绿随机分给各块），团块的体积靠彩绘：背光侧月牙 `shade`、下缘一串扇贝形描线、受光侧从 matt 里刮出叶形 |
| 小叶子用描线勾轮廓，缩小后成了一团乱线 | 暗部画实心叶片（不透明度约 0.8）再刮出叶脉；亮部从 matt 里刮出叶形 |
| 细枝也切成玻璃，两条铅夹一道棕线像梯子；冬树成了一个「Y」 | 玻璃只切树干和宽 16 px 以上的大枝，大枝要弯；更细的枝和小枝用 `trace` 画在天空上 |
| 太阳周围另切一圈放射块，外沿多出一道圆形铅条 | 区域交界一定是铅条：同一片天空只用一次 `glass()` |
| 燕子像喷气式飞机 | 用从下往上看的雨燕剪影：镰刀形后掠弯翼、短身、深叉尾 |
| 横铁条正好横穿知更鸟的头和鸟巢 | 先定铁条高度（范例是 286 / 490 / 694），鸟、巢、太阳、字都避开 |
| 每个铅条交叉处都扎一个铜丝结，铁条像一排缝线 | 每根铁条只扎几个小结（已处理） |
| 题字带从中间切开，铅条正好穿过字 | 短题字的饰带用一整块料 |
| 树干被切成一节节竹子 | 树干和大枝用竖向拉长的块（`aspect=1.8, angle=π/2`） |
| 秋天透过树冠的画枝和画的叶子拼成像字母的黑块 | 画枝只画在露出天空的地方（`trace(..., clip=)`） |
| 上铅之后整扇窗发暗发闷 | 铅条下面的玻璃压暗只做 4.5 px、0.22（已处理） |
| 带 `--stages` 和不带出的图不一样 | 渲染时才生成的噪声和气泡改用构造时就定好的种子，阶段快照不再挪动随机序列（已处理） |
| 动图 3.3 MB：每个阶段墙面溢光都跟着窗变，整面墙在每次叠化里重编码 | `daylight()` 之前墙用固定的中性溢光；叠化帧里色差 ≤ 18（关键帧 ≤ 6）的像素沿用上一帧（1.8 MB） |
| 小形状也开整幅数组做模糊和遮罩：44 秒、1.6 GB | `matt / shade / circle / ellipse / poly / saddle_bar / lancet` 都只在包围盒里算（约 4 秒、约 1 GB） |

**泥金手抄本**

| 问题 | 改法 |
|---|---|
| 羊皮纸像拉毛墙、灰泥墙 | 封皮的细颗粒起伏误铺到了书页底下：封皮起伏只加在露出的封皮上；皮面起伏只用低频（尺度约 240 px、振幅约 6 px，靠近页边加倍） |
| 正文溢出压进圆图；首行红字标题被挤成两行 | 动笔前用 `text_width` 量：x 高 18 px 时一行约 45 个字符，标题写短；正文按行数算好再定图的位置 |
| 首字母旁窄栏两端对齐后，词距大得像空洞 | 拉伸上限 2.2 个词距；放不下就按拉丁音节加连字号断词（已处理），还不行就左对齐 |
| 打磨金箔像一块黄颜料，带横向稻草纹 | 金是镜子，颜色就是它映出的房间：让平面的反射落在窗光的斜坡上（窗方向 z≈0.8），给石膏底加打磨留下的大尺度起伏（尺度约 60 px、±2 px），才映得出明暗带；拉丝纹振幅压到 0.04，金箔接缝 0.12 |
| 同样的金，在跨页一边亮、另一边发橄榄黑 | 相机放远（z≈6000，接近正交），明暗只看表面法线，不随画面位置漂移 |
| 星盘的网架金色太粗，盖住盘面，看不出是星盘 | 网架变细（黄道环 0.06R、横梁 0.017R、星指针 0.024R），盘面加方位圈（过天顶和天底的圆，只画地平线以上），墨线 0.75 px、不透明度 0.85 |
| 圆图里的行星名字摞成一竖排 | 每个名字沿自己的环写，角度错开成阶梯（150° → 36°） |
| 恒星天里的金星被群青盖掉 | 先贴金后上色，颜料遮罩要乘 (1 − 金)，绕开已贴金的地方 |
| 常春藤叶子像金色小铃铛，压到正文和边框条上 | 叶形要有两侧尖角和深缺口；叶、花、金珠放下前先检查：叶尖和两侧角离正文至少 9 px，离边框条至少「叶长 + 3」px；卷须不能弯回去穿过边框条 |
| 首字母上的白色短划像随手画的加号 | 去掉短划，只留沿笔画中线的白线和三点一组的白点 |
| 次级首字母的红色卷须压进红字标题，像鱼骨 | 卷须放在字左侧 16 px 外；钩子只朝页边一侧，长短交替，末端打卷 |
| 背面透过来的字太重，像渲染错误 | 透印不透明度 0.03，模糊 1.6 px |
| 动图里玫瑰色和金色被量化成褐色 | 调色板取样时，饱和像素算 5 倍 |

**达·芬奇手稿**

| 问题 | 改法 |
|---|---|
| 排线像一团卷毛、像波浪 | 不要把一条长排线切成一串各自弯曲的短笔首尾相接；手是一排一排地排线：同一层排线共用一组带轻微错位的「排界」，长线只在排界处断开，留 0–2 px 的空隙或交叠；手抖 jitter 降到 0.1，所有笔画朝同一边微弯 |
| 蒙皮整片涂黑，像一幅幅窗帘 | 每片蒙皮用 `between()` 取「从前一根肋到后一根肋」的 0→1 场，明暗取 t²：靠前那根肋留白、靠后那根肋才排线、最深处才交叉，蒙皮才会鼓起来 |
| 翼后缘一段段往外鼓 | 蝙蝠翼蒙皮在两个肋尖之间往里凹；镜像到左翼时法线方向会反，弯曲方向按「朝翼内某一点」决定，不按左右写死 |
| 翼形又钝又圆，像一面帆 | 指骨肋从腕点呈扇形散开，翼尖收成尖角，越往外翼弦越短 |
| 红粉笔鸟翼像梳子、像流苏 | 羽毛不画完整轮廓：只画宽羽片的外缘、圆的羽尖和窄羽片的尾段（`overlapped=True`），一片压一片；羽尖要圆不要尖；初级飞羽比次级飞羽长，外侧几根张开约 7° 成「指」；宽羽片靠外缘处排线（被下一根羽毛压出的影子），覆羽画成成排的小圆弧再揉开 |
| 单根羽毛像一片带叶脉的叶子 | 羽枝每 2.6 px 一根、很细很轻，朝羽尖斜；加一段光秃的羽管和两处羽枝分叉的缺口 |
| 扇形排线时有时无，一块一块 | 明暗值不要正好压在排线阈值上（噪声会让它一半过线一半不过），整片均匀的排线 shade 给得比阈值高一截 |
| 尖笔辅助线横穿整页、像划痕 | 圆规只在需要的地方刻一小段弧（翼尖 ±12°），中心线、肩线可以长；刻痕没有颜色，只靠侧光的明暗 |
| 曲柄看起来像个 L 形铁片 | 曲柄臂在轴端加一个套轴的凸台，木把手更长更粗，并用点划线示意它沿轴滑上去 |
| 分解图的零件和机翼撞在一起 | 先算好投影：相机方位角改为 +22°，轴往左下伸，轴缩短到 250，曲柄落在空白处 |
| 旧纸太干净、像新打印纸 | 除了霉斑还要大片柔和的泛黄云斑（纸的施胶老化不均）；霉斑要有清楚的小核，不能只是一团模糊的晕 |
| 霉斑的晕被切成小方块 | 每个斑点的计算框要按晕的半径（约 7 倍斑点半径）开，不能按斑点本身 |
| 墨色发灰 | 铁胆墨水偏暖：淡处琥珀褐、浓处深赭，叠处更深；纸纤维把墨线轻轻打散 |
| 飞鸟序列只是一串「V」 | 每只鸟加身体、尾羽、腕部转折和翼尖张开的初级飞羽，按 `phase` 走完一次上扑下扑 |

**剪影**

| 问题 | 改法 |
|---|---|
| 垂卷用一串椭圆叠成，像一串葡萄 | `ringlet()`：一条左右摆动、每圈鼓一下、越往下越细的长条（约 5 圈），金粉只在每圈上画一笔短斜线 |
| 头发的金粉画成随机小弧，像一串气泡；改成 10 条等距平行线，又像条纹头盔 | 只画 6 条左右长短不一的发丝，顺着发团从额头梳向脑后，线宽约 2 个设计单位 |
| 帽檐是等粗的直条，像一根签子插穿了头 | 帽檐沿一条 S 形中线 `snip`：靠帽冠处最厚（约 22），两头收到 3，前沿上翘，后沿下垂 |
| 帽冠的褶纹全汇到一点，像顶帐篷 | 褶纹画成互不相交的短弧；帽冠上沿用 `scallop` 鼓出一排小圆，做出抽褶感 |
| 蝴蝶结是两个圆环加圆洞，像眼镜，还被帽檐挡掉一半 | 环拉长成椭圆，中间剪一道窄缝（宽约 0.12 倍）；放在帽檐上方、背后是底卡的地方 |
| 猫又高又窄、头很小，像保龄球瓶 | `sheet(warp=)` 只改比例、不重敲坐标：头放大 1.12 倍并下移，身体朝垫子压到 0.62，臀部加宽；再剪出眼睛和前后腿之间的空隙 |
| 船的两面三角帆互相重叠、又压着前桅帆；主帆和后纵帆连成一大块黑 | 第二面三角帆整个放在第一面后缘的右边；主桅最下面的大横帆收起（帆桁下一排小圆）；后纵帆缩到主上桅帆下面；上下横帆之间至少留 14 个设计单位；三角帆保留尖角，只让后缘鼓 |
| 侧框外圈的红色底漆磨成一大片一大片棕斑 | 底漆只在棱顶露出：噪声尺度 5 px（2× 采样再 ×2），阈值 0.66–0.80，强度 0.6 |
| 名字和小字贴到黑色描边带上 | 椭圆越往下越窄：先按 hw = rx·√(1−(dy/ry)²) 算那一行的半宽再定字号；名字 32 px，小字不超过 25 个字符 |
| 墙纸条纹笔直清晰，像现代印刷 | 印版遮罩加约 ±0.9 px 的横向漂移，奶白色墨不透明度 0.66，每幅纸单独印、各自错位和对花，再加一层泛黄 |
| 动图里深红丝绳被量化成棕色，玻璃反光下的黑纸出现一块块色阶 | 调色板样本加权：饱和像素 ×5、深红 ×15、被反光抬亮的黑（亮度 0.075–0.28）×7，再叠同一张 4×4 Bayer（约 ±2.4 级） |
| 峰值内存 1.1 GB：整幅 `blur` 和细尺度 `noise2d` 产生大量 float64 中间数组 | 挂镜线、护墙线的阴影只和 y 有关，按一维算；整幅细噪声换成白噪声加 3×3 均值；2× 金框按 192 行一带分带渲染（重叠 24 行），降到约 0.6 GB |

**凸版印刷海报**

| 问题 | 改法 |
|---|---|
| 大面积实地满是白点，像加了噪点滤镜，木刻黑块发灰 | 漏白（salt）只出现在实地内部，纸齿阈值 0.975 以上，约占 1%–5%；边缘积墨处几乎不漏；木活字凹坑软斑浓度降到 0.15–0.35 |
| 大象前腿斜着伸到老远的鼓上，像撑地的肘 | 以髋为轴把身体整体抬起（约 22°），四条腿都竖直向下；鼓放在前肩正下方，鼓顶 = 前肩高度 + 前腿长（腿比后腿短 4%） |
| 大象像秃头圆球加一根水管，耳朵像第二个头、像垂耳狗、像兜帽 | 象鼻根部宽约一个头高（104→26 渐细），并进前额；耳朵是扇形：前缘弧形贴在眼后，顶端低于头顶让圆顶露出来，后缘波浪、下端收尖；加小象牙和张开的嘴 |
| 腿根在身体里画出一圈圆头轮廓，像插上去的柱子 | 先刻远侧两条腿；近侧身体、头、鼻、近侧腿、尾巴合成一个剪影只刻一圈外轮廓，内部只补大腿、肘几笔短轮廓线 |
| 排线整片一样密，大象像条纹木桶 | 排线线宽跟随明暗（`hatch` 的 tone），lo 约 0.3：背上最亮处线条自然收尖消失；身体用绕远处圆心的弧线，腿用竖线，鼻子斜线加横向皱纹 |
| 鼓上的条纹印成一整块红色楔形 | 条纹相位 = arcsin(u)·9 − y/9，一圈正面看到 4–5 条斜纹，上下各留出箍 |
| 象头上的小帽画成红色贝雷帽、像一颗樱桃 | 非斯帽用直边多边形 `poly`（不用平滑闭合曲线），流苏从帽顶垂到后面 |
| 象鼻尖碰到钢丝，看着像要去抓钢丝 | 鼻尖离钢丝留约 70 px，卷向演员 |
| 画面偏右，桅杆和大象之间空出一大片 | 大象放在两根桅杆正中；背后加雕版衬线：横向细线、椭圆向外渐隐，每样东西周围先 blur 出一圈白再清掉 |
| 舞者的站立腿是两根细线，平衡杆横穿胸口 | 腿加粗（17→9 px）、加黑色舞鞋；手肘弯下，杆放到腰的高度 |
| 马戏圈的圈沿伸出画面右边；锯末和地面投影太黑，像污渍 | 圈的半宽按两根桅杆间距算；锯末密度 0.0035、只在脚边，投影用横向排线（tone 0.55） |
| 纸边的小缺口是一颗颗黑点，像墨团 | 缺口只留 3 个、3–7 px |
| 峰值内存 1.5 GB | `press` 按 240 行一带处理；木刻印完就释放整页遮罩（1.19 GB） |

**苏联构成主义**

| 问题 | 改法 |
|---|---|
| 网格塔印成网点后是一根实心的点状锥体，看不出格子 | 每节每组杆件从 24 根减到 16 → 8 根（越往上越少），杆件加粗（0.55 m 往上收到约 0.27 m）；远侧半圈的杆件反照率最多 ×6.5，显得浅；雾的距离从 520 m 改到 2600 m（否则全塔被雾冲成均匀的中灰）；塔照片加网前的模糊从 0.3 格降到 0.12 格（`soften=0.12`），塔顶的横担才分得开 |
| 收音机照片认不出：喇叭正对镜头成了一个黑球，电子管是白疙瘩 | 喇叭口轴线与视线约成 60°，侧面看得到外扩的喇叭口和口内暗面；黄铜反照率 0.45、金属度 0.5，底座改黑漆；玻璃管反照率 0.42，加一道内部阳极暗带 |
| 收音机面板像照相机（两个一样大的象牙色刻度盘像镜头） | 改成一个黑色胶木大刻度盘（镍圈 + 白刻线）加两个小旋钮、接线柱、铭牌，机顶加蜂巢线圈，喇叭到机身拉一根软线；照片放大到 1.16 倍，网点格从 6.5 px 改成 5.5 px |
| 编号方块里的数字不见了 | 黑色电波弧压在了标注上，黑上加黑挖不出空。电波只占楔形 ±9° 的范围、到喇叭口为止，标注都放在电波范围外 |
| 电波弧铺满半张纸，像梳子、像肋骨 | 波前只画在楔形附近，从塔尖画到喇叭口；线宽随半径变细（`grow=-0.045`）；上沿只到 +6.5°，别碰到标题 |
| 斜排的标注里，数字跑到方块外面 | 方块和数字都用 `along()` 从同一个左下角算；不要一个绕自身中心转、一个绕角点转 |
| 剪下的照片放在纸色上，剪刀留的白边看不出来 | 让照片压在红块、黑条或楔形上：收音机后面垫一块从黑条升起的大红块，楔形一直伸到喇叭口下面 |
| 红块只从照片缝里露出几条细缝，像渲染错误 | 红块要比照片大一圈（高 410 px），从黑条一直顶到标题下面；剪刀剪不进的窄缝用 `close=` 桥接，被照片围住的洞自动填平（剪刀只能绕着外轮廓剪） |
| 楔形末端的直边在喇叭口旁边露出一个红角 | 楔形只伸到喇叭口再多 20 px，半角 5.6°，宽度和喇叭口差不多，末端整个藏在剪下的照片下面 |
| 折痕太弱，像画上去的一根细线 | 折痕处墨层断断续续地裂开（约 2–3 px 宽），两侧约 ±3 px 的磨损带墨最多淡 22%，再加一亮一暗的折棱和一道污渍带 |
| 图钉孔像一个黑点 | 孔周围加一圈偏向一侧的锈色晕 |
| 红版套印错位后，画面右边缘露出 2 px 纸白 | 错位前先把版用边缘复制 pad 8 px：成品是印完再裁切的，边上不会露白 |
| 填洞后剪下的照片反而整片印满底色网点 | `ImageDraw.floodfill` 对 `Image.fromarray()` 得到的图不起作用（不报错），要先 `.copy()` 再填 |

**装饰艺术**

| 问题 | 改法 |
|---|---|
| 车鼻前下方一圈圈指纹状条纹，法线乱跳 | 「把截面朝一个点缩放」得到的不是合格的距离场（命中点残差 0.19 m）；改成竖直核心线段膨胀 R 的精确截面（直侧壁、圆车顶、底部平切），车鼻只沿轨道方向拉伸（只会低估距离，步进安全），残差降到 0.008 m |
| 车头竖直，像电车 | 核心前缘做成斜线（`rake` 约 2.2 m），车鼻向前下方倾斜 |
| 头灯飘在车头前面；奶油窗带在车鼻上被一刀竖直切断 | 斜车头实际伸出的长度比 nose_len 长得多（垂直斜边膨胀）：用二分法实测车鼻表面，头灯、条纹收拢、车鼻素色端头都以实测车尖为准；条纹在最后 14% 前停下，窗带收成尖头 |
| 车身只有几道细金线，远看是一整块红 | 加奶油色窗带（1.95–3.15 m）和上下金线；腰线在车鼻上按截面坐标向车鼻收拢，成为速度线 |
| 钟和扇形冠顶浮在楼顶上面，戳进标题 | 钟画在顶层楼身上（`top_windows=False` 把这层的窗空出来），冠顶从顶层上沿起；近景楼顶都压在副标题下方 |
| 副标题两侧的金线穿过副标题文字 | 先画副标题拿到宽度，金线从标题两端画到副标题外侧 28 px |
| 头灯是一大团白光，像一只眼睛 | 灯球半径 0.3 m、铬圈 0.47 m，光晕 80 / 10 px，自发光 0.85 |
| 头灯光束指回车身 | 光束终点取 60 m 前方会跑到相机后面、投影翻转；终点改为 min(60, 0.6·Z/dz) |
| 头灯照亮前方铁轨，但画面里看不见 | 护栏 0.56 m 高、相机只比轨面高 1.4 m，桥面被护栏挡住；护栏降到 0.25 m、相机抬到轨面上 2 m；掠射角的朗伯项只有约 0.1，改成包裹式（×5 封顶），铁轨成了从左下引进画面的两道亮线 |
| 喷枪颗粒太粗，光束和射线像撒了沙 | 颗粒 = 固定噪声 × 0.2 × d(1−d)：只在薄涂处有，实涂和空白处没有；射线的颗粒 0.45 |
| 河面倒影是一块块迷彩斑 | 波纹按压缩后的深度坐标取噪声，横向拉长约 90 倍、只用两层：近处长而稀、远处细而密 |
| 月亮倒影太弱，黑天空和月亮反射得一样多 | 镜像按亮度加权（0.45 + 1.3·smoothstep(0.35, 0.85, 亮度)），月亮和窗灯拉出一条光路 |
| 车窗倒影成了高架下面一串孤立亮点 | 范例里关掉（`lights(r, reflect=False)`）；要用就把拉伸调长 |
| 月海是脏兮兮的斑点 | 月海用 smoothstep 柔边、浓度 0.13、颗粒 0.25 |
| 动图里红色车身被量化成棕色色块，天空出色带 | 加权调色板（饱和像素 ×5、亮像素 ×2）+ 每帧同一张 4×4 Bayer（约 ±2.4 级）；量化只用 255 个真实颜色，占位透明色用品红，否则最暗的像素被当成透明（自检 9 帧对不上） |

**黄金时代漫画**

| 问题 | 改法 |
|---|---|
| 羽状排线像一排梳齿、像尺子刻度：等长、等距、完全平行 | 长度跟着两层慢噪声起伏（0.25–1.15 倍），间距 ±30%，每根略弯、偏离平行约 4°；起笔压在阴影边上，越往亮处越短 |
| 羽状排线穿过白色色环上的字，RS-1 被看成 RS-T | 排线的 clip 去掉文字所在的区域 |
| C40 M70 Y100 的棕色（头盔、山体暗面）在 11 px 粗网下花成发绿的斑 | 棕色不用蓝版：M70 Y100 + 黑 40% / 70%（`BROWN` / `DARK_BROWN`） |
| 天空七条等宽色带像一面旗；中间几档两版都挂网，花点太闹，压住人物 | 色带用 `edges=` 指定不等宽；过渡档尽量只挂一个版（蓝 40%、蓝 20%、黄 40%），两版叠网只留在顶部一两档 |
| 月亮光晕的同心色环盖过所有色带，在橙色带里切出一个蓝色圆盘 | 去掉光晕；`rings()` 只用在单一色带里 |
| 顺风飘的围巾正好盖住后座小狗的头，小狗只剩一团白 | 围巾往后上方飘（漫画夸张），小狗后移；先画后座再画前座；狗脸用纯白（不挂网）配黑耳、黑鼻、金色护目镜 |
| 护目镜比脸还大，像第二个头；挡风玻璃像两颗牙、像多出来的尾翼 | 护目镜只露一只镜片推在额头上；去掉挡风玻璃，只留座舱口沿 |
| 座舱里的人画在船体之后，下半身露在船体外面 | 先画人，再画船体：`part` 会擦掉被挡住的墨线和颜色，最后补座舱口沿 |
| 尾喷管是一块挂网灰方盒；火焰外层深橙和橙色天空同色，又被下尾翼和烟挡掉 | 喷管涂黑加银色口沿；火焰由外到内红、深橙、橙、黄、白五层，烟只吞掉火焰末端，下尾翼缩小，去掉横穿舷窗的中间尾翼 |
| 烟团是锯齿星形、挂橙色网，像一堆石头 | 烟团用近圆形加轻微起伏，白底；只在右下月牙挂黑 20%，靠火焰的一侧挂黄 40% |
| 右边台地看不出是悬崖：斜面、羽线、暗面混成一团，暗面花成墨绿 | 平顶加竖直崖壁：崖顶下一道黑影，裂缝从黑影往下用 `feather(along=(0, 1))`；崖脚另起一道碎石坡，换一种颜色 |
| 地平线正好穿过 Sparky 的头；他在画面里太小，故事的笑点看不见 | 地平线下移到胸口；人物放大 1.15 倍，飞走的帽子挪开、别压在手上 |
| 动图超过 2 MB（2.34 MB），网点缩小后成了摩尔纹 | 缩到 720 宽时用 BOX 不用 LANCZOS：1.79 MB，网点仍隐约可见 |
| 内存峰值 1.25 GB | 网点阈值图等缓存改成 float16；印刷按 180 行一带处理；刊名只在自己的裁切区里算；做旧效果只作用在各自区域：峰值约 0.85 GB |

**波普丝网**

| 问题 | 改法 |
|---|---|
| 好几格里多出贯穿整格的黑斜线 | 闭眼弧线的粗细用 `sin(πt) ** 0.7`，末端 sin 是 −1e-16，幂运算得 NaN，多边形就连到了窗口原点。`stroke()` 里已把宽度 `nan_to_num` 并截到 ≥ 0；自己写 `profile` 时先 `clip(sin, 0, 1)` |
| 底色上一道道白色横纹，像划痕 | 底色 `dry=0`，`streak` 约 0.012；笔触纹拉长（长约 140 px、宽约 7 px）；干笔拖痕只出现在形状边缘一圈 |
| 缺墨时黑块里露出规整的方格编织纹，像数码图案 | 布纹对墨膜的影响降到 0.035；露底主要来自顺刮板方向的条纹、约 5 px 的团块噪声和一块干版斑 |
| 闭眼的 ∩ 太细，下面又垫一块椭圆眼影，读成「眉毛 + 睁着的眼」 | 闭眼弧线宽约 0.10 单位，两端收细；开心那格不垫眼影，改用腮红；困那格的眼影做成闭合的眼皮形状，只在闭眼线上方 |
| density 0.84 的缺墨格，脸几乎印不出来 | 0.92–0.95 是「缺墨但认得出」，1.0 正常，1.1–1.15 墨多；flood 超过约 0.5 会糊掉半张脸 |
| 墨多那格，远侧耳朵糊成一顶黑礼帽；耳朵压平后，耳背描边和头顶虎斑纹交叉成一个 X | 耳朵外转超过 40° 时，耳窝只印网点、只描上沿；被耳朵挡住的那道头顶虎斑纹不印 |
| 远侧耳朵的阴影和耳背描边分成两块：描边像一根飘着的棍子，耳毛像羽毛球 | 远侧整只耳朵做成一块暗面，一直到外缘；耳毛 4 根，宽约 0.026 单位 |
| 吐舌头只是嘴下面一团红点 | 舌头色块伸出嘴外（下沿到约 0.74 单位）；黑版给舌尖描 U 形轮廓和一道中线 |
| 每格边缘一圈浅色细线，像内描边 | 漆脊的 relief 从 0.9 降到 0.35 |
| 左肩上的长弧形虎斑纹像几道「翅膀」 | 受光一侧的胸前斑纹不印实线，只印成网点带（tone 约 0.38） |
| 峰值内存 1.08 GB | 脚本把 60 多张整窗遮罩放进列表再 `np.stack`；`canvas()` 和合成时又整幅算临时数组。改成用 `np.maximum` 就地累积遮罩，颜色层按格现算，布纹和合成按 180 行一带计算，降到约 0.46 GB（改遮罩累积这一步前后，成品逐字节相同） |
| 动图里黑网点和六套配色的混合色量化错（p99 误差 100） | 调色板样本里，已上黑版的后半关键帧 ×3，再用 `kmeans=4` 精修：p99 降到 39，误差大于 70 的像素从 3.7% 降到 0.03%，体积不变 |

**ASCII 字符画（行式打印机）**

| 问题 | 改法 |
|---|---|
| 箭身和烟用 I H M N 之类字母铺调子，远看像一行行单词「IMM」「HNM」 | 填色字符只用符号：箭身 `. : + % # #@`，烟 `. : % @ # #@`；字母只留给真正的文字 |
| 按形状相关度给线条挑字，桁架塔变成一串 `<> <>`、`^V` | 改成按方向和位置选：方向在真实像素里量（格子是瘦高的），陡的 \| / \\，平的按在格里的高低选 `' - . _`，两条线交叉才用 X / + |
| 斜线、竖线同时压到左右两格，到处是 `//`、`\\`、`)\|` | 同一条线、同一方向的相邻两格只留笔画更多的那格（非极大值抑制；斜线还要求字符相同，免得吃掉尖顶的 /\\） |
| 桁架斜撑交点落在四格交角，中间成了 `\_/`、`/-\`，没有 X | 斜撑按「一列一行」走、过格心：塔宽取 6 列（中间 5 格），交点正好落在格心出 X；横撑放在行中心，压在行界上会被两行平分、谁也不到阈值 |
| 箭身和黑色滚转标记、尾焰之间也描出一圈轮廓，箭身里横七竖八的 \| 和 ---- | 角色分组（`group='rocket'`）：同组之间不描边，只有对外的剪影描边 |
| 烟云每个云团都描边、调子又加误差扩散，底下一片乱码 | 云团用 `edge='all'` 但 `inner_max=0.5`：只在亮的云顶画 ( ) 和 .-'，暗部只靠调子；光从上方来、云底再加一层自身阴影（`lift`），抖动降到 0.2；云团改成少而大（半径 5.5–10 列） |
| 字太干净，像激光打印或屏幕截图 | 字模先按墨的洇开模糊约 0.5 px，再和色带织纹、纸面齿纹一起过阈值：力度够就满铺，力度弱就变细、断开、起麻点，而不是变灰；改用粗体字模 |
| 火焰内部加了一根根 ' ! 的条纹，像引号和珠串；内焰锥画成一串 () | 尾焰从箭身底部直接长出来、和箭身同组，不用随机抖动 |
| 尾焰只剩两条 ( ) 竖线围出的空白，读不出是在点火 | 尾焰做成从喷口往下变宽的亮柱：外层 `plume` 角色按离轴距离 u 从 . 过渡到 % @ # 的烟套（u>0.45 起变暗），内层 `core` 角色是几道从喷口散开、沿长度明暗闪动的条纹（! \| 在喷口、往下变成 : . '），两层都不加随机抖动才对称 |
| 下面两团前排烟云从两侧压住亮柱，形成往下收窄的漏斗，看着像火焰变细 | 前排烟团外移（离轴 13.5 列），亮柱两侧各放一个小烟团接住烟套，中间那团的云顶 ____ 正好接住柱底 |
| 头锥用平滑闭合曲线，肩部鼓出一块，又一版太钝像圆顶 | 头锥按弹头曲线 半宽 = R·(2s − s²) 逐点算多边形，不用样条 |
| 左边天空加一层随机点「晨雾」，像纸上的脏点，还在第 94 列切出一条竖边 | 去掉；空的天空留白，右侧大空位放一座远处水塔平衡构图 |
| 表头「RUN … PAGE」和参考图的格式太像 | 换成 JOB 4471 / SHEET 2 这类自编字段 |
| 最底下一行烟云被画面下边切掉半行字 | 改用 8½ 英寸深的连续纸（`page_in=8.5`，51 行一页），`ppi` 调小让整张纸连同上下两道撕线都在画面里，左右露出桌面；画面在 `page_rows − 2` 行 `erase` 掉，留两行页边再到撕线；横向撕线和折痕加深 |
| 太阳只是一圈线加几根离得很远的光芒，鸟东一只西一只，像随手的符号 | 太阳盘面用 . : 填出边缘发暗（中间 .、边上 :），光芒贴着盘面、8 根等长；鸟排成一队人字形往太阳方向飞 |
| 动图里红圆珠笔被量化成灰色 | 红色像素太少，加权也抢不到颜色：调色板单独给红色留 14 格 |
| 峰值内存约 1 GB | 纸张按通道就地合成、成图分 480 行一带合成，降到约 0.7 GB |

**低多边形**

| 问题 | 改法 |
|---|---|
| 悬崖上满是竖向的绿条纹，平台上反而是横向岩层 | 材质错位一格：每个面的材质取剖面里靠内侧的那个点（两端下标取小的），悬崖才贴岩层、平台才贴灌丛 |
| 河床三角形一块块从水面里戳出来 | 画家排序按平均深度，埋在水下的河床有时算得比水面「更近」：完全在水下的面干脆不生成（`canyon(buried=)`），水面带 −2 的排序偏置，像贴花一样后画 |
| 水面一片发白的青色 | 涟漪短划减到 16 条、颜色压暗，水面 spec 0.35；逆光看水本来就亮，别再加 |
| 构图照搬参考图：飞机在正下方、大环正居中、后面的环一个个叠在环里 | 赛道改成右转弯，相机放到飞机右后方，用 `aim()` 把飞机放到左下三分点，金环沿对角线往右上排开 |
| 外弯的岩壁把天空整个挡住，太阳和光晕都没了 | 峡谷整体压低（`height=0.75`），相机降到飞机上方约 2.6 m，视场 52°，留出约两成天空 |
| 从正后方追尾看，飞机只剩一个「十」字，还被画面底边切掉 | 相机放在右后上方，能看到机翼上表面；飞机离镜头约 11 m |
| 一级台阶和相机差不多高，被看成一道发亮的裂缝 | 相机高度避开台阶高度（台阶约 11.8 / 20 m，相机约 16.6 m） |
| 金环又细又发橄榄色，看不出多面体 | 管径 0.6（半径 3.4）、12×5 个面、暖金 #ffaa1a、glow 0.28、spec 2.0、shine 4：暗面偏橙、亮面发黄、迎光的面闪白 |
| 逆光下飞机和金环发灰发闷 | 着色光和画里的太阳分开设：`light(lift=26)` 把着色光抬高 26°（当年的游戏也这么做） |
| 光晕里的空心圆像多出来的金环，正中的绿色六边形像一块石头 | 光晕只用小圆点和实心六边形；画面中心附近只放 2 px 的小点，大六边形放到远端并调淡 |
| 「"」加粗后两撇连成一道横线，「1'07"42」读成「1'07-42」 | 两撇之间空两列（`'#  #'`）；零不加斜杠，斜体时才不像 8 |
| 螺旋桨盘几乎看不见，像一块灰斑 | 半透明盘 alpha 0.36，再加一圈更亮的桨尖圆环 |
| 杜松在逆光里成了黑剪影 | 树带 glow 0.3，叶色提亮 |
| 动图 2.08 MB，金色 HUD 偏棕 | 缩小用 BOX 而不是 LANCZOS（像素硬边不出振铃噪点），调色板样本里饱和像素 ×5：1.63 MB |

**喷漆模板涂鸦**

| 问题 | 改法 |
|---|---|
| 每张模板四周都有一圈带麻点的大方框（风筝、燕子、字周围最明显），一开始还是贴着卡纸边的几条细直线 | 喷的区域按 2.5 倍喷幅往外扩，卡纸外的漆才落得到墙上；扫过卡纸边的「卡纸残影」系数降到 0.0035；扫到头折返时只减速到 0.55，不再在边上积一大团 |
| 所有边缘都是 6–8 像素的毛刺，像发霉，清晰核心没了 | 卡纸翘起量不再按「离胶带越远越高」涨到 1：平贴为主（0.15 + 0.35 × 离胶带距离 + 0.5 × 局部鼓起）；底下渗漆只用 1.8 像素模糊、权重 0.2 + 0.5 × 翘起量；外溢雾化 7 / 24 像素两层，强度 0.022 / 0.012 |
| 滴痕到处都是：白漆滴痕从围巾一路流过外套和裤子，每座桥上面都往下滴 | 只从真正的下边缘起滴（往下 7 和 12 像素都是空的，桥不算）；数量按 amount × min(26, 2 + 过量/40) 封顶，白版 0.06、灰版 0.2、黑版 0.7；滴痕的凸起降到 0.45 + 0.25 × 宽度/3，否则被后面几版盖住了还以白色棱线透出来 |
| 三版叠起来灰糊糊：灰版跟黑版几乎一样深，白版喷不匀一片麻点，黑版只剩细边 | 灰改 #7b7c79；白漆遮盖力 2.0、喷 3 层；黑版阴影加深（躯干 34、腿 18 / 44 像素），`shade_side(wobble=)` 让阴影边像手刻的 |
| 燕子像喷气式飞机 | 弯月形后掠翅（一上一下）、细身子、长长的分叉尾 |
| 围巾先像面条，再像「VAV」字母，最后像一只举起来带手指的条纹胳膊 | 从脖子前一个结里分出两条长短不一的窄尾巴，往前稍往上飘；只画横条纹，尾巴上不加阴影月牙；流苏扇形散开、互不相碰（碰上了会围出孤岛被桥切成方框） |
| 帽檐压住眼睛，下巴下的黑阴影像小胡子 | 帽檐整体上移 6 个单位，眼睛放大、鼻头往前凸、嘴是轮廓上的一个缺口；下巴阴影改进灰版、变细 |
| 小孩像在往前走，躯干像一只蛋 | 上半身绕髋部再后仰 9°，前腿伸直、脚跟着地脚尖翘起，后腿弯着撑住；羽绒服缩短到胯部、收窄 |
| 黑版快照里卡纸整张喷成黑的，看不出刻了什么 | 卡纸上的漆按「粉尘」画（0.82 × (1 − e^−0.55D)，透出牛皮纸），切口边按卡纸厚度一侧亮一侧暗 |
| 墙像木板墙，木纹太清楚；裂缝像画上去的黑线；泛碱像一条白色虚线 | 木纹起伏减半，只在一块块区域里压出来；加水泥色斑和浮浆；裂缝变细变淡；泛碱用噪声断开 |
| 市政灰漆像一块模糊的圆角方块 | 改成一道道竖着的滚筒：每道起止高度不同（上下边缘成台阶）、两头发干拉丝、相邻两道重叠处颜色深一点，底下的旧签名透一点出来 |
| 动图里红风筝变成砖红色、粉色签名没了 | 调色板样本加权：红 ×12、其他饱和色 ×5、黑 ×3，再叠同一张 4×4 Bayer（约 ±2.4 级）；透明占位色用品红，不用黑 |

**刺绣徽章**

| 问题 | 改法 |
|---|---|
| 牛仔布像印出来的 45° 斜条纹，白纬又亮又粗 | 经纱比纬纱密（1.5 × 2.5 px），斜纹约 60°；纬纱只露一小点、每点露多少随机；经纱加竹节纱的染色起伏和磨白；2× 渲染再缩小 |
| 缎面边框像条形码，黑白条太硬 | 缎面线截面压扁（起伏 ×0.6），线与线之间的暗沟只降到 0.74 |
| 填充绣满片像砖墙 | 针孔凹陷只暗 30%；每行起针位置加 ±6% 的漂移 |
| 缎面平平的，看不出「线的光泽渐变」 | 缎面长线按衬垫拱起（拱高约 0.11 × 线长，最多 3.2 px），一根线上就有从亮到暗的过渡 |
| 深色线被高光冲淡，指南针每个尖角的明暗两半分不出来 | 高光整体 ×0.62；亮半边别用太亮的颜色（亮红 #cf4637 / 暗红 #721a14） |
| 雪峰亮面太白，雪顶糊进山里 | 山的亮面用中灰蓝，白只留给缎面雪顶；阴面明显更暗 |
| 火焰用竖向缎面，长线被拆成交错短针，看着像填充绣 | 针向横着走（约 ±15°），maxlen 放到 90；外焰、中焰、内焰一层压一层 |
| 湖面波纹穿过帐篷，还伸出徽章压到边框和牛仔布上 | 细节针按层次排在压在它上面的东西之前画；`run(clip=徽章遮罩)`，路径留在边框以内 |
| 异形章圆角的缎面边框出现放射状摩尔纹 | 按相位梯度算每处针距，小于约 2 px 时把单根线的起伏淡掉；圆角半径至少是边框宽度的两倍（34 px 对 17 px） |
| 锁边上周期性的暗条和小黑点，底下的颜色从里面透出来 | 两个原因：2.6 px 的绕线和像素网格拍频，改成按 (s, d) 4 次子采样再平均；PIL 粗折线画的带状区域有针眼大的洞，再做一次 5×5 最大值滤波 |
| 弧形条章的字挤到两头的锁边上 | 字号 42、跨角 98°，字间距 0.05 倍字号 |
| 整组徽章太小，画面上方三成空着 | 设计坐标统一乘 1.14 再上移；针单独按画布坐标摆，别跟着放大推出画面 |
| 动图里金色锁边和营火被量化成橙褐色 | 调色板样本里暖色饱和像素 ×5、亮色 ×2（暖色平均误差 9.5 → 5.6） |

## 四、做成动画

- 各画风都有 `stage(name)` 和 `save(path, stages_dir)`，按阶段依次淡入叠化，就是「一幅画被逐步画出来」。README 里的动图就是这样做的。
- 动图规格（多数现有动图和后来新增的都一致）：720×405；每个阶段停 900 毫秒，再用 5 帧（每帧 90 毫秒）叠化到下一阶段，最后一帧停 2600 毫秒，无限循环。后来新增的动图所有帧共用一张 256 色调色板，文件小、不闪烁。
- 调色板别只取最后一帧：满屏单色（黑板的墨绿、赛博朋克的夜色）会吃掉色位，彩色部分被量化成灰。黑板按加权像素样本做中值切分（彩色像素 ×5、亮色 ×2）；赛博朋克从全部关键帧的拼图取 255 色，留 1 个透明色标记「和上一帧相同」的像素，并去掉 Pillow 每帧重复写入的局部调色板（3.8 MB → 1.8 MB）。
- 调色板的另外几条经验（新增的几种里反复出现）：
  - 小面积的点睛色（报刊拼贴的芥末黄纸片、单线画的琥珀色窗、柔光 3D 的黄球）会被量化成土黄、米黄或平色片：取调色板样本时饱和像素 ×5 左右，限定色板的画风可以把色板色强制放进调色板。
  - 大片渐变（弥散玻璃的背景、单线画的深蓝底、Synthwave 的天空）出现一圈圈色带：量化前叠一张固定的 4×4 Bayer 抖动，每帧同一张，「和上一帧相同」的透明差分照样有效。
  - 标记「和上一帧相同」的透明占位色不要用黑色：最暗的阴影像素会被当成透明，自检时大批帧对不上，改用纯品红这类画面里没有的颜色。
  - 最后一个 `stage()` 和成品完全相同时，Pillow 会把相同的帧合并，按帧数自检会报 EOFError：`save()` 前不要紧挨着再调一次 `stage()`。
  - 卡通手绘的抖线动图只抖墨线，铅笔稿和颜色不动，否则每次叠化都整片重编码，体积翻倍。
- 后来新增的十六种（岩画到刺绣徽章）动图又反复用到几条通用做法；改版的动图脚本放在各画风自己的工作目录（如 `claude_drawing/mosaic_work/`），没有进仓库：
  - 加权调色板：取样时饱和像素 ×5 左右、亮色 ×2；红、金、橄榄绿这类面积小的点睛色加权也抢不到颜色时，单独给它们留调色板位（先中值切分出约 240 色，再从这类像素里单独切 6–14 色补上；饱和色多的可按色相区等量抽样，单独分几十色）。
  - 大片渐变、深色上的反光出色带：量化前每帧叠同一张固定的 4×4 Bayer 抖动（约 ±2.4 级）。
  - 满屏网点或硬边像素（漫画网点、低多边形）缩到 720 宽时用 BOX 不用 LANCZOS，否则网点成摩尔纹、硬边出振铃，体积也更大。
  - 满屏细纹理（灰泥、石子、玻璃）每次叠化都会改掉大半像素：叠化帧里和屏上已显示颜色只差一点（约 10/255）的像素沿用上一帧、记成透明，自检按实际显示的帧逐帧比对；墓室壁画、马赛克、彩色玻璃花窗都是靠这一条（再加各自的小改动，见第三节）把动图从 3 MB 多压到 2 MB 以下。
- 形变动画可以直接出真动画：`Morph.at(keys, T)` 给出全局时间 T 的轮廓，逐帧渲染即可。
- 更细的逐笔动画：把一组笔画单独画到透明层上导出，再用 Motion Canvas 遮罩按顺序显现。这个还没做成现成接口。

## 五、文件

```
lib/core.py            公共底层（噪声、模糊、样条、遮罩、毛笔、字体）
lib/inkpaint.py        水墨
lib/watercolor.py      水彩
lib/papercut.py        剪纸拼贴
lib/colorpencil.py     韩国彩铅
lib/anime.py           日本动漫
lib/editorial.py       编辑风手绘
lib/oilpaint.py        油画厚涂
lib/ukiyoe.py          浮世绘木版画
lib/pixelart.py        像素风
lib/clay.py            黏土定格
lib/cyanotype.py       蓝晒
lib/stitch.py          十字绣
lib/panel.py           复古仪器面板
lib/sticker.py         贴纸拼贴 · 小票
lib/notebook.py        实验笔记本 · 贴纸
lib/chalk.py           黑板板书
lib/cyberpunk.py       赛博朋克
lib/cartoon.py         卡通手绘（逐帧手绘）
lib/isometric.py       等轴 2.5D
lib/lineart.py         单线画
lib/soft3d.py          柔光 3D
lib/morph.py           形变动画
lib/newscollage.py     报刊拼贴
lib/aurora.py          弥散玻璃（弥散渐变 · 玻璃拟态）
lib/bauhaus.py         包豪斯几何（丝网印刷海报）
lib/synthwave.py       复古 Synthwave
lib/perler.py          拼豆（钉板、熔珠小管、熨烫融合）
lib/petroglyph.py      岩画（凿刻砂岩：沙漠漆、锤击凹坑、磨刻、剥落）
lib/tomb.py            古埃及墓室壁画（灰泥、红格红稿、分栏、象形文字、剥落）
lib/mosaic.py          罗马马赛克（底稿取色、沿轮廓排石、光环、灰缝、铭牌、脱落）
lib/stainedglass.py    彩色玻璃花窗（玻璃切块、grisaille 彩绘与银染、铅条焊点、透光）
lib/illuminated.py     泥金手抄本（羊皮纸、宽头鹅毛笔哥特体、打磨金箔、尺规图解）
lib/codex.py           达·芬奇手稿（铁胆墨水鹅毛笔、左手排线、红粉笔、尖笔圆规、镜像手写、机械零件分解图）
lib/silhouette.py      剪影（黑纸剪影、薄金粉、椭圆金框、木版印花墙纸）
lib/letterpress.py     凸版印刷海报（木活字、红黑双色错版、木刻插图）
lib/constructivism.py  苏联构成主义（红黑两版、套印错位、网点照片拼贴、剪刀留边、折痕老化）
lib/artdeco.py         装饰艺术（Art Deco 流线型海报：喷枪渐变 + 遮片硬边、交替射线、阶梯高楼、3D 流线型列车、Deco 字母）
lib/comic.py           黄金时代漫画（毛笔墨线、Ben-Day 网点、四色错版、新闻纸）
lib/popart.py          波普丝网（沃霍尔式：手涂撞色平涂、错位的照相黑版、刮印的墨不匀）
lib/lineprinter.py     ASCII 字符画（行式打印机：绿条连续纸、按区域选字、叠打、色带渐淡）
lib/lowpoly.py         低多边形（1999 年代 3D：软件光栅化、平面着色、仿射贴图、逐顶点雾、15 位色抖动、点阵 HUD）
lib/stencil.py         喷漆模板涂鸦（清水混凝土墙、卡纸模板与桥、喷雾、滴痕）
lib/patch.py           刺绣徽章（牛仔斜纹、填充绣 / 缎面绣、锁边、热切边、手缝针线）
examples/*.py          范例脚本；*.jpg 成品；drawing_*.gif 逐步画出的动图
中文字体：自动找 Kaiti/Songti（macOS）、Noto CJK（Linux）、KaiTi/SimSun（Windows），或设 INKPAINT_FONT
西文字体（后来新增的画风用）：core.latin_font(style) 按 sans / sans_bold / rounded / script / hand / typewriter 等找系统字体，可用 INKPAINT_FONT_<STYLE> 指定；字体文件不要放进仓库
```
