示例

问题

在颜色填充上代码存在缺陷,譬如:

根据目前的思路无法解决,且越简单的图像越容易出现该问题,大多数(针对复杂图像)时候工作正常。主要原因在于,假设有两个同心圆,SVG会填充两圆之间的区域(下图左),但在翻译SVG指令并使用turtle绘制时我无法做到这一点(下图右):

另一种思路(来自于tfx2001)是,将一张位图根据颜色分离成多张纯色子图(使用K均值聚类),然后将每张子图转换成SVG格式,再进行绘制,从而避免了上述颜色填充问题,譬如:


附:贝塞尔曲线

二阶贝塞尔示例:

Bessel曲线的特征十分容易掌握,给定任意的nn个点,且对于任意的tt0t10\leq t \leq 1)来说,在每两个相邻点之间的连线上找到一个“T点”(姑且这么称呼吧),记相邻的这两个点一前一后分别为AA,BB,有ATAB=t\frac{AT}{AB}=t成立,其中ATAT表示AATT点的距离,ABAB表示AABB的距离,于是对这nn个点如此计算可以得到n1n-1个“T点”,然后对这n1n-1个点重复上述操作,直至最后只剩下一个“T点”,这就是初始nn个点在某一tt下的Bessel曲线上的轨迹点

推导一下二阶Bessel方程(一阶,n=2n=2,没意义),图中P0P_0,P1P_1,P2P_2是初始的三个点,分别称为起点、控制点和终点:

由:P0P0,1P0P1=P1P1,1P1P2=P0,1P0,2P0,1P1,1=t\frac{P_0P_{0,1}}{P_0P_1}=\frac{P_1P_{1,1}}{P_1P_2}=\frac{P_{0,1}P_{0,2}}{P_{0,1}P_{1,1}}=t,有:P0,1P0P1P0=t\frac{P_{0,1}-P_0}{P_1-P_0}=tP0,1=(1t)P0+tP1P_{0,1}=(1-t)P_0+tP_1,以此类推,有:{P0,1=(1t)P0+tP1P1,1=(1t)P1+tP2P0,2=(1t)P0,1+tP1,1\begin{cases}P_{0,1}=(1-t)P_0+tP_1 \\P_{1,1}=(1-t)P_1+tP_2 \\P_{0,2}=(1-t)P_{0,1}+tP_{1,1}\end{cases}

将前两个式子代入第三个得到:P0,2=(1t)2P0+2t(1t)P1+t2P2P_{0,2}=(1-t)^2P_0+2t(1-t)P_1+t^2P_2,其中P0,2P_{0,2}是轨迹点,P0P_0,P1P_1,P2P_2都是已知点,轨迹点坐标设为(x,y)(x,y),三个已知点分别设为(x0,y0)(x_0,y_0),(x1,y1)(x_1,y_1),(x2,y2)(x_2,y_2),于是有:
{x=(1t)2x0+2t(1t)x1+t2x2y=(1t)2y0+2t(1t)y1+t2y2\begin{cases} x=(1-t)^2x_0+2t(1-t)x_1+t^2x_2 \\ y=(1-t)^2y_0+2t(1-t)y_1+t^2y_2 \end{cases}

六阶贝塞尔示例:

绘制爱心: