2.1 解决思路
由于笔画之间存在交叉重叠(c),若要实现笔画拆取,就需要将笔画交接处的凹点连通起来。这些处于交叉处特殊的拐角点称为corner,连通两个corner形成bridge,表明他们同属于一个笔画。
当顺时针跟踪端点:
-
连通前:依据轮廓点顺序。
-
连通后:会依据bridge直接联通对应corner,从而实现笔画的拆分。
因此,笔画拆取工作主要分为以下四步:
2.2 EndPoint Parsing Corner检测
在Hanzi Writter开源库中,笔画拆取算法主要围绕corner展开。那corner是什么呢?详细来说,corner是位于两个笔画轮廓交界的特殊端点,通常情况下,他会有另一个corner与之匹配,如C1和C2。C1和C2相邻且处于笔画A的轮廓同侧,连通C1和C2就可以将笔画A和笔画B拆分开来,得到笔画A自己的轮廓数据。这些corner具有显著的局部特征,它们是字形的凹点,经过该点处的path会沿着顺时针急剧弯曲。计算出所有端点的角度和距离,判断是否拥有该特征,就可以检测哪些端点为corner。
function Endpoint(paths, index) {
this.index = index;
const path = paths[index[0]];
const n = path.length;
this.indices = [[index[0], (index[1] + n - 1) % n], index];
this.segments = [path[(index[1] + n - 1) % n], path[index[1]]];
this.point = this.segments[0].end;
assert(Point.valid(this.point), this.apoint);
assert(Point.equal(this.point, this.segments[1].start), path);
this.tangents = [
Poi