昨天晚上,我做梦一直在梦同胚流形。也不知道为什么,梦里没有人在给我讲定理,我却一直在告诉自己:要用同胚流形来分析书法。今天早上醒来,我就真的开始琢磨这件事。
最初的直觉很简单:同一个字从宋体变成黑体,从楷体变成行书,甚至从一种手写状态变成另一种手写状态,轮廓、粗细、角度和比例都可以变化,但只要关键连接没有断、包围关系没有换、该有的环和分叉还在,它仍然是那个字。这很像拓扑学关心的事情——不问精确长度,只问结构在连续变形中是否保持。
可是一醒来我又立刻意识到,光靠拓扑不够。拓扑可以回答“这个字还成立吗”,却回答不了“这是谁写的”“笔锋为什么这样转”“墨迹为什么枯、润、涩、散”。于是第二个判断也很快出现:必须加入分形几何来处理笔触,而且还不能只算一个分形维数。
到这里,这个想法已经不再是把两个听起来很高级的名词拼在一起。它开始变成一个可以写代码、可以失败、也可以被反例推翻的算法框架。
一、拓扑先回答:这个字还成立吗
严格地说,汉字骨架通常不是普通流形。“十”“木”“米”里的交叉与分叉,其局部邻域并不像一条普通直线。更合适的对象,是嵌入平面的图,或者带奇点的分层空间。
设一个字的中心线骨架为 KH,把它在平面中加粗成正则邻域,再沿第三维加厚:
这样,笔画不再只是黑色像素,而是管道;交点和分叉成为连接结构;包围与闭环成为可计算的拓扑关系。字体变化可以写成一族连续映射 Φt。如果整个过程中没有断裂、粘连、闭环生成或闭环消失,就可以把它看作同一拓扑类型内部的流动:
这一层守住的是字的身份。它关心连通分量 β0、独立闭环 β1、端点、分叉、交叉、部件邻接和嵌套关系。但它的能力也到此为止。两个完全不同的字可能具有相同的 β0 和 β1;同一个字也可能在拓扑完全一致时,写得一个像原帖,一个完全不像。
二、我的四层模型
所以我把最初的“同胚流形+分形几何”又扩成了四层:
T 是拓扑骨架:哪些笔画连接,哪里分叉,哪里形成闭环,哪个部件包围哪个部件。
G 是几何结体:长度、角度、曲率、宽高比、重心、部件距离和疏密。拓扑保证“还是这个字”,几何决定“像不像这张原稿”。
ℱ 是有限尺度分形笔墨:边缘粗糙、飞白孔隙、墨色密度和不同尺度上的空隙分布。它不移动骨架,只改变笔画表面。
q 是潜在运笔动力学:位置、压力、速度、笔锋角度、湿润状态和停顿。它试图回答“这样的静态墨迹,可能由怎样的动作写出来”。
最后的墨迹不是某一个层直接给出的,而是一个渲染过程:
这四层之间必须有明确边界。分形纹理不能为了“更像墨”而制造新的骨架毛刺;动力学不能为了“更像运笔”而把闭环写断;拓扑也不能因为自己很重要,就把所有飞白都当成结构错误。
三、为什么分形几何不能只剩一个数字
真实书法不是数学意义上无限尺度的严格分形。纸张纤维、扫描分辨率和像素大小给出了下限,字和纸面的尺寸给出了上限。更准确的说法,是有限尺度统计自相似。
如果只算一个全局盒计数维数,两个笔墨气质完全不同的字也可能得到相近结果。因此我把分形层拆成广义维数、多重分形谱、局部维数和空隙度。对于墨色测度 μ,广义维数可以写成:
空隙度则帮助区分“均匀细碎的飞白”和“集中成块的缺墨”:
这一层的原则是:宏观骨架保持安静,微观边缘才允许复杂。早期版本没有守住这个尺度边界,结果“笔墨纹理”变成了肉眼可见的毛刺。
四、静态图像背后还缺一支正在运动的笔
仅凭最终墨迹,不能唯一恢复真实笔顺和运笔。同样的轮廓可能来自不同的速度、压力、倾角和停顿。因此我没有把算法输出叫作“还原真实笔法”,而是把它定义为满足静态约束的一种潜在动力学解释:
其中 p 是压力,v 是速度,θ 是笔锋方向,η 是含墨或湿润状态。算法在转折附近降低速度、提高压力,在提笔处收窄宽度,在内部节点禁止虚假的起笔和收笔。这样可以避免“轮廓像剪出来的”,但它仍只是受约束的解释,不是从照片中读取了不存在的时间信息。
五、把想法写成算法
真正进入代码后,流程变成了:
参考笔迹分割 → 字形统计 → 字体先验选择 → 二值轮廓 → 拓扑保持细化 → 聚类骨架图 → 连续中心线 → 运笔动力学 → 有限尺度笔墨 → 拓扑与形态门控。
骨架图中的分叉像素先聚成节点,避免把一个栅格交叉口误算成十几个分叉。每条图边从端点或分叉追踪到下一个节点,再用 Ramer–Douglas–Peucker 算法去除像素阶梯,用语义转角把直行、折笔和弯钩分开。
后来,为了解决“所有笔划都像软管一样弯”的问题,我又加入近直笔段约束。对两个语义转折之间的路径,计算相对于端点弦的最大偏差:
当 ρ ≤ 0.10 时,把这段视为近直笔段,直接用弦代替;超过阈值的回环、弯钩和弧线继续保留曲率。字级扰动也从正弦位移改成仿射变换,因为仿射变换有一个很重要的性质:直线变换以后仍然是直线。
质量选择不是把所有误差揉成一个分数。否则,纹理得分很容易“买下”一个结构错误。我采用字典序门控:先要求拓扑不变,再要求形态距离和持久拓扑距离过线,最后才允许分形与动力学决定谁更好。
六、迭代不是越来越好,而是不断发现新的错
这一轮开发最有价值的部分,并不是某一张最终图,而是每次“看起来更高级”的修改都可能造成负优化。版本记录因此不能只保存最后一张。
- 像素骨架版。结体与参考字体相对接近,但每个相邻像素被当成微小线段,笔画边缘出现毛刺,转折像锯齿。
- 连续曲线与带状硬笔。用整条路径、三次贝塞尔和连续宽度场替换微线段,形态更连贯;但控制柄与端点帽仍会制造不自然的鼓包。
- 四层合并。拓扑、结体、分形笔墨和运笔动力学第一次同时进入渲染。整体气质接近了一些,却在“为”的右侧和下方生成小黑点。
- 局部显著性伪枝清理。黑点被定位为中轴细化产生的短伪枝,经圆形端帽放大后形成。新规则只删除位于字形外包络、具有成对端帽或正交径向结构、且不改变 β0 和 β1 的分支。
- 近直笔段约束。去掉中心线正弦漂移,压低可见尺度的边缘起伏,把浅弯笔段规整为直线。总曲率变差下降了一半以上,但笔划仍没有真正解决。
七、为什么现在的笔划仍然不行
目前最核心的问题,是算法虽然有了拓扑骨架,却还没有真正得到书写意义上的笔划。
字体轮廓的中轴,是一个几何对象;人写字时的一笔,是一个时间对象。中轴会在粗笔画的圆头、回环和高曲率位置自然长出分支,这些分支在几何上合理,却未必对应真实运笔。把中轴图的一条边直接当成一笔,等于把“形状从哪里最厚”误当成“笔从哪里经过”。
第二个问题是,直与弯不能只靠一个比例阈值决定。同样的弦偏差,在横画中可能是噪声,在撇、捺、竖钩中却可能是决定字势的部分。算法还缺少横、竖、撇、捺、折、钩、提等笔画原语,也缺少部件语义对几何的约束。
第三个问题来自静态信息的不充分。照片告诉我墨在哪里,却不告诉我笔何时到达、停了多久、有没有回锋。动力学只能给出一种可能解释。如果不引入真实书写轨迹、笔顺先验或更强的物理笔尖模型,转折就仍可能“形状差不多,动作不可能”。
所以这项工作目前最诚实的结论不是“我已经生成了这个人的字体”,而是:我搭出了一个能把错误分层的研究框架。现在我可以明确说,哪里是拓扑错,哪里是结体错,哪里是笔墨错,哪里是运笔解释错。仅仅做到这一点,就比一个总的相似度分数更接近书法临摹的真实问题。
八、下一步:从骨架边走向真正的笔划
下一版不会再继续堆纹理。重点会转向语义笔划:
- 把字体中轴图与有序笔画数据对齐,区分几何分支和真实落笔;
- 建立直线、圆弧、渐变曲率、折与钩的笔画原语;
- 在转折处使用提按和速度连续性,而不是仅靠圆形补丁填缝;
- 让分形纹理严格停留在有限尺度边界,不再参与中心线形态;
- 把人工视觉判断作为门控的一部分,任何让结体变差的“优化”都自动回退。
我仍然认为最初那个梦抓住了正确的入口:书法不是一张轮廓图,而是一个多尺度结构系统。拓扑描述字是否还成立,几何描述结体像不像,分形描述笔墨气息,动力学描述它是否真的能这样写出来。现在失败的地方,不是这个分层失效了,而是“几何骨架”到“时间笔划”之间还有一道没有跨过去的桥。
原创研究声明
本文记录的“拓扑骨架+几何结体+有限尺度分形笔墨+潜在运笔动力学”书法分析与生成框架,以及围绕该框架完成的 v0.1–v0.5 算法迭代,由苏西的界于 2026 年 8 月 8 日提出、组织并开发。灵感直接来自 2026 年 8 月 7 日夜间反复出现的“用同胚流形分析书法”梦境。
拓扑学、图骨架、同胚、分形几何、多重分形、持久同调、贝塞尔曲线和运笔动力学本身都是既有数学或计算工具;本文不主张发明这些基础概念。本文所主张的原创性,在于问题的提出、四层结构的组合方式、各层之间的约束边界、书法生成中的分层质量门控,以及这一套方法在真实代码中的连续迭代。
- 作者:苏西的界
- 首发日期:2026年8月8日
- 首发网站:苏西的界博客
- 引用或转载时,请保留文章标题、作者、日期与规范链接。
跳到正文