本发明属中文信息处理汉字字形生成技术领域。 目前,生成宋体字的方法有两类,一类是经过训练的人员随手写成的,另一类是由计算机生成的。计算机生成宋体字用的数学模型有两种,一种是点阵数学模型,另一种是在点阵基础上建立的向量数学模型。为了压缩点阵模型的数据量,CN85108434在一种事先给定的点阵模型中提取八种基本笔划,用其组成独体字和偏旁部首,合体字由偏旁部首生成。EP0095536A1则在一种事先给定的点阵模型中,将字的笔划分为规则和不规则两类。规则笔划单独定义,另外构成一个含有不同规格规则笔划的子库,组字时按代码调用。不规则笔划用折线(向量)定义,一字一定义。前者属点阵模型,后者属向量模型。
用人工手写方法生成的宋体字的质量与书写人的技术水平关系甚大一般未经严格训练的人是难以写出美观地宋体字的。
目前,计算机生成汉字的方法,都是以某一种规格的点阵模型为母体的。汉字本质上是非数字量的图形,数字化为点阵模型以后,就不可避免地丢失信息,存在误差。用这些方法将汉字放大时,误差也一同放大,误差大到一定程度就明显破坏了汉字的美观。使用点阵模型将字放大到一定程度,会产生明显的锯齿边。使用向量模型将字放大到一定程度造成的累积误差,会使笔划的型状和相对位置产生明显的偏差,字中的曲线也明显地变成了折线。因此,为了使计算机能高质量地生成各种尺寸的汉字,就需要在计算机中存贮以不同规格点阵模型为母体的多个字库。另外,虽然有多种压缩点阵模型数据量的方法,但这些方法的压缩比不大,由于压缩量不大,同时又要存贮多个字库使字库本身占用了相当可观的计算机存贮资源。
目前,在点阵模型和向量模型的基础上,以偏旁部首为单元组合成字是以压缩数据为目的的。例如CN85108434。这些方法除存在只能适当变倍的限制外,还有另一种限制。在两个汉字中,宋体字亦不例外,同样的偏旁部首为几何意义的全等图形的概率极低。因此,以偏旁部首组合成字由于存在基本图形形状和位置的误差,使字的美观程度受到限制。
本发明的目的是提出一种方法,按照这一方法,使用总量不大的同一组数据就可以无误差地生成没有尺寸限制的美观的宋体字。
本发明的内容为:每个宋体字是由代码(代表笔素)与坐标组成的偶对集合定义的。设宋体字为A,则该宋体字的定义满足:
A={c1,(x1,y1);…;ci,(xi,yi);…;cn,(xn,yn)}i=1,2,…,n
其中ci,(xi,yi)为一个偶对,偶对中的ci是代表笔素的代码,(xi,yi)是笔素ci所在的坐标。
笔素是以一系列数值定义的,是由直线和弧形成的封闭图形。笔素定义数值的意义与封闭图形的形状一一对应。根据封闭图形形状或定义数值意义的不同,笔素分为若干种,每种笔素又按数值的不同分为若干规格,每一个笔素有一个唯一的代码。
由笔素定义数值的意义,可以按解析几何的方法列出方程,解出生成直线和弧所需的一切参数,产生笔素的封闭图形。
一、与生成笔素有关的公式。这些公式是按解析几何的方法推导的
(1).由两点和斜率求弧的公式(以下简称点斜公式)。
已知:点b1(x1,y1),b2(x2,y2),及b3(x3,y3)或弧b1b2在b2处的斜率k,直线b2b3与弧b1b2切于b2.
求:弧b1b2的园心0(x0,y0),半径R.
k=(y3-y2)/(x3-x2)
y0= (2(x2+ky2)(x1-x2)-x1+x2-y1+y2)/(2[k(x1-x2)-y1+y2])
x0=x2+k(y2-y0)
R=(x1-x0)+(y1-y0)
(2).由两点和垂线求弧的公式(以下简称点垂公式)。
已知:点b1(x1,y1),b2(x2,y2);弧b1b2在点b2处的斜率为。
求:弧b1b2的园心0(x0,y0)及半径R。
y0=y2
x0= (x1-x2+(y1-y2))/(2(x1-x2))
R=x2-x0
(3).已知:弧上一点b(x,y),园心0(x0,y0)。
求:弧在b点的切线斜率k。
k=(x-x0)/(y-y0)
(4).已知:直线上两点b1(x1,y1),b2(x2,y2)。
求:直线的斜率k。
(5).已知:弧上一点b处的切线斜率k1。
求:该点的法线斜率k。
k=-1/k1
(6).由两点和半径求弧的公式(以下简称点径公式)。
已知:b1(x1,y1),b2(x2,y2)为弧上两点,R为弧的半径。
求:弧的园心0(x0,y0)。
d=(x2-x1)+(y1-y2)
@=arcsin(d/2R)
t=π-@-arcsin[(x1-x2)/2Rsin@]
x0=x1-Rcost
y0=y1-Rsint
(7).由直线和园求连接弧的公式(以下简称线园公式)。
已知:点b2(x2,y2),b3(x3,y3)为一直线上两点,b0(x0,y0)为一半径为y0的园的园心。
求:与直线b2b3相切于b3、且与园相切于b1(x1,y1)的弧在园上的切点b1。
d=(x2-x3)+(y2-y3)
cos@=(x3-x2)/d
sin@=(y2-y3)/d
x3′=x3cos@-y3sin@
y3′=x3sin@+y3cos@
x0′=x0cos@-y0sin@
y0′=x0sin@+y0cos@
AA=x3′
BB= ([y3′+y0-y0′-(x3′-x0′)±2y3′y0])/(2(y3′+y0-y0′))
A=AAcos@+BBsin@
B=-AAsin@+BBcos@
k=(B-x0)/(A-x0)
x1=x0-y0/(1+k)
y1=k(x1-x0)+y0
二、各种笔素的形状、定义数值的意义(参见附图)及生成的方法。
1.三角形(图1)。代码从O起始。由a1,a2,a3三个点的坐标值定义。封闭图形由直线a1a2,a2a3,a3a1组成。从a1开始,顺序连接三点是为三角形。
2.四边形(图2)。代码从1000开始。由a1,a2,a3,a4四个点的坐标值定义。封闭图形由直线a1a2,a2a3,a3a4,a4a1组成。从a1开始,顺序连接四点是为四边形。
3.五边形(图3)。代码从2000开始。由a1,a2,a3,a4,a5五个点的坐标值定义。封闭图形由直线a1a2,a2a3,a3a4,a4a5,a5a1组成。从a1开始,顺序连接五点是为五边形。
4.竖撇(图4)。代码从3000开始。由a1-a7七个点的坐标值定义。其中a1,a4,a5是顶点。a2,a3,a6,a7是弧与弧的切点。封闭图形由左侧曲线a1a7a6a5,右侧曲线a1a2a3a4和顶部直线a4a5组成。左右侧曲线分别是弧a1a7,a7a6,a6a5和弧a1a2,a2a3,a3a4连于切点a7,a6和a2,a3所组成的线段。两侧曲线在a4,a5处的切线为垂线。生成方法为:
(1).分别关于点a5,a6;a4,a3用点垂公式(2)求出园心、半径,作弧a5a6,a4a3.用式(3)求出两弧在a6,a3处的斜率k6,k3。
(2).分别关于k6,a6,a7;k3,a3,a2用点斜公式求出园心、半径,作弧a6a7,a3a2。用式(7)求出两弧在a7,a2处的斜率k7,k2。
(3).分别关于a1,a7,k7;a1,a2,k2用点斜公式(1)求出园心、半径,作弧a1a7,a1a2。
(4).以直线连接a4a5.
5、斜撇(图5)。代码从4000开始。由a1-a5五个点的坐标值定义。其中a1,a3,a4是顶点,a5,a2是直线与弧的切点。封闭图形由左侧曲线a1a5a4,右侧曲线a1a2a3和顶部曲线a3a4组成。左右侧曲线分别是直线a4a5和a2a3与弧a1a5和a1a2连于切点a5,a2的线段。生成的方法为:
(1).以直线连接a4a5,a4a3,a3a2。分别关于点a4,a5;a3,a2用公式(4),求出直线a4a5,a2a3的斜率k5,k2。
(2).分别关于k5,a5,a1;k2,a2,a1用点斜公式(1)求出园心、半径,作弧a1a5,a1a2。
6、长撇(图6)。代码从6000开始。由a1-a7七个点的坐标值定义。其中a1,a4,a5是顶点,a2,a3,a6,a7是弧与直线的切点。封闭图形由左侧曲线a1a2a3a4、右侧曲线a1a7a6a5和底部弧a4a5组成。左右侧曲线分别是直线a1a2,a1a7与弧a2a3,a7a6与与直线a3a4,a6a5连于切点a2,a7,a3,a6的线段,第二段直线的长度可以为零。底部弧a4a5在与左侧曲线a1a2a3a4的交点a4处的切线方向与左侧曲线在a3处的法线方向一致。生成方法为:
(1).以直线连接a1a2,a1a7,a3a4,a6a5。分别关于,a1,a2;a1,a7用式(4),求出直线a1a7,a1a2的斜率k2,k7.
(2).分别关于a3,a2,k2;a6,a7,k7用点斜公式(1)求出园心、半径,作弧a2a3,a7a6。再关于弧a2a3用公式(3)求出弧a2a3在a3处的斜率k3.
(3).关于k3用公式(5)求出弧a2a3在a3处的法线斜率k3′。关于k3′,a5,a4用点斜公式(1)求出园心、半径,作弧a4a5。
7、短撇(图7)。代码从5000开始。由a1-a3三个点的坐标值和两个半径值R1,R2定义。三个点是顶点。封闭图形由左侧弧a1a2,右侧弧a1a3和底部弧a2a3组成。R1是弧a1a2的半径,R2是弧a1a3的半径,底部弧a2a3在与左侧弧a1a2交点a2处的切线方向与左侧弧a1a2在a2处的法线方向一致。生成的方法为:
(1).分别关于a1,a2,R1;a1,a3,R2用点径公式求出园心作作弧a1a2,a1a3。
(2).关于弧a1a2用公式(3),(5),求出弧a1a2在a2处法线斜率k2。关于k2,a3,a2用点斜公式(1)求出园心、半径,作弧a2a3.
8、雨滴点(图8)。代码从7000开始。由a1-a3三个点和园心a0的坐标值定义a1,a2中只有x1,x2是已知的。其中a3是顶点,a1,a2是弧与弧的切点。封闭图形由左侧弧a1a3,右侧弧a3a2和园心为a0的底部弧a1a2组成。底部弧a1a2与左侧弧a1a3连于切点a1,与右侧弧a2a3连于切点a2.生成方法为:
(1).以下列公式求出a1中的y1和a2中的y2.
y1=y0-y0-(x1-x0)
y2=y0+y0-(x2-x0)
k2=-(x2-x0)/(y2-y0)
k1=-(x1-x0)/(y1-y0)
以a0为园心,以y0为半径,作弧a1a2。
(2).分别关于a1,a3,k1;a2,a3,k2用点斜公式(1)求出园心和半径,作弧a1a3,a2a3。
9、象牙点(图9)。代码从8000开始。由a3,a4,a5三个点和园心a0的坐标值定义。其中a4是顶点,a5,a3分别是弧a1a5,a2a3与直线a4a5,a4a3的切点。封闭图形由左侧曲线a4a5a1,右侧曲线a4a3a2和园心为a0的底部弧a1a2组成。底部弧a1a2分别与左右侧曲线a4a5a1和a4a3a2连于切点a1,a2。生成方法为:
(1).以直线连接a3a4,a4a5。
(2).分别关于a4,a3,a0;a4,a5,a0用线园公式(7)求出点a1,a2的坐标值。式中,前者取负号,后者取正号。以a0为园心,y0为半径作弧a1a2。
(3).分别关于a4,a3,a2;a4,a5,a1用点斜公式(1)求出园心、半径,作弧a1a5,a2a3。
10、刀捺(图10)。代码从9000开始。由a1-a6六个点的坐标值定义。其中a1,a3,a4,a6为顶点,a2,a5为直线与弧的切点。封闭图形由左侧曲线a1a2a3,右侧曲线a4a5a6和底部弧a3a4组成。左侧曲线为直线a1a2与弧a2a3连于切点a2组成的线段。右侧曲线为直线a5a6与弧a5a4连于切点a5组成的线段。底部弧a3a4在与左侧曲线a1a2a3的交点a3处的切线方向与左侧曲线a1a2a3在a3处的法线方向一致生成方法为:
(1).以直线连接a1a2,a1a6,a6a5。
(2).分别关于a1,a2,a3;a6,a5,a4用点斜公式(1)求出园心、半径作弧a2a3,a4a5。
(3).用公式(3)、(4)求出弧a2a3在a3处的法线斜率k,关于a3,a4,k用点斜公式(1)求出园心、半径作弧a3a4
11、戈柄(图11)。代码从10000开始。由a1-a6六个点的坐标值定义。其中a1,a3,a4,a6为顶点,a2,a5为直线与弧的切点。封闭图形由左侧曲线a1a2a3、右侧曲线a6a5a4和底部弧a3a4组成。左侧曲线为直线a1a2与弧a2a3连于切点a2组成的线段。右侧曲线为直线a5a6与弧a5a4连于切点a5组成的线段。生成方法为:
(1),(2)与刀捺(图10)相同,第(3)步为以直线连接a3a4。
12、戈钩(图12)。代码从11000开始。由a1,a2两个点的坐标值和一个角度值@定义。a1,a2是顶点。封闭图形由左侧折线a2a3a4、右侧弧a1a2和底部弧a1a4组成。左侧折线a2a3a4中的直线a3a4与戈柄(图11)中的底部直线a3a4重合。右侧弧a1a2在上顶点a2处的切线与横轴的夹角为@底部弧a1a4在左端点a4处的切线方向与戈柄(图11)左侧曲线a1a2a3在a3处的切线方向一致。生成方法为:
(1).戈钩(图12)总是与戈柄(图11)共同使用的。以戈柄(图11)中弧a2a3的园心O(x0,y0)、半径R、a3的坐标值(x3,y3)代入下式,求出戈钩(图12)中a4的纵坐标y4。
y4=y3-(y0-R-(x3+x1-x0))
其中,x1是戈钩(图12)中a1的横坐标。
用公式(3)求出戈柄(图11)中弧a2a3在a3处的斜率k3。关于k3,a1,a4用点斜公式(1)求出园心,半径作弧a4a1。
(2).以k=tg@,a1,a2用点斜公式(1)求出园心、半径,作弧a1a2。
(3).设戈柄(图11)中点a3,a4有纵坐标之差
d=y4-y3
则戈钩(图12)中的a3,a4点的坐标满足
x4=x3+d
以直线连接戈钩(图12)中的a3a2,a3a4。
13、提点头(图13)。代码从12000开始。由a1-a5五个点的坐标值定义。其中a1,a5是顶点,a2,a3,a4是直线与弧的切点。封闭图形由左侧曲线a1a2a3、右侧直线a4a5、顶点直线a1a5和底部弧a3a4组成。左侧曲线a1a2a3为弧a1a2与直线a2a3连于切点a2的线段。底部弧a3a4与左侧曲线a1a2a3连于切点a3,与右侧直线a4a5连于a4。生成方法为:
(1).以直线连接a2a3,a4a5,a1a5。
(2).关于a2,a3,a4;a3,a2,a1用点斜公式(1)求出园的半、园心,作弧a3a4,a1a2。
14、提点尾(图14)。代码从13000开始。由a1-a3三个点的坐标值和数值c定义。其中a1,a3是顶点,a2是弧a5a4在a5,a4处切线的交点。封闭图形由左侧直线a1a3,右侧曲线a3a5a4和底部直线a1a4组成。提点尾总是与提点头共同使用的。右侧曲线是直线a3a5与弧a5a4连于切点a5形成的线段。数值c是a2到a5的距离。生成方法为:
(1).关于提点头(图13)的右侧直线a4a5用公式(4)求出斜率k4,以提点尾(图14)的a2,a3用公式(4)求出直线a2a3的斜率k5。以k5,k4,a1代入下列公式求a4,a5点的坐标值(x4,y5),(x5,y5)。
y4=y1-c
x4=x1-c/k4
d=(y4-y1)+(x4-x1)
x5=x1+d/k5+1
y5=y1+k5(x5-x1)
关于k1,a5,a4用点斜公式(1)求出园心、半径、作弧a4a5。
(2).以直线连接a1a3,a1a5,a1a4。
15、斜钩(图15)。代码从14000开始。以a1-a3三个点的坐标值和角度@定义。三个点是顶点。封闭图形由左右侧弧a1a2,a2a3和顶部直线a1a3组成。左侧弧a1a2在下端点a2处的切线与横轴的夹角为@。右侧弧a2a3在上端点a3处的切线方向与四边形(图2)中的直线a2a3的方向一致。斜钩总是与非矩形四边形(图2)共同使用的。生成方法为:
(1).关于四边形(图2)中直线a2a3,用公式(4)求出其斜率k。关于k,a2,a3使用点斜公式(1)求出园心、半径,作弧a2a3。以k=tg@,a1,a2用点斜公式(1)求出园心、半径,作弧a1a2。
(2).以直线连接a1a3。
16、竖钩(图16)。代码从15000开始。以a1-a3三个点的坐标值和角度值@1,@2定义。三个点是顶点。封闭图形由左右侧弧a1a2,a2a3和顶部直线a1a3组成。左右侧弧a1a2,a2a3在下端点a2处的切线与横轴的夹角分别为@1,@2。生成方法为:
(1).分别关于k=tg@1,a1,a2;k=tg@2,a2,a3用点斜公式(1)求出园心、半径,作弧a1a2,a2a3。
(2).以直线连接a1a3。
17、园钩(图17)。代码从17000开始。以a1-a5五个点的坐标值和角度@定义。五个点是顶点。封闭图形由左侧折线a1a5a4,右侧弧a2a3,底部弧a1a2和顶部直线a3a4组成。左侧折线a1a5a4是弧a4a5与直线a1a5相连的线段。且弧a4a5在顶端a4处的切线为垂线。右侧弧a2a3在顶端a3处的切线也为垂线。底部弧a1a2在与右侧弧交点a2处的切线与横轴的夹角为@。生成的方法为:
(1).分别关于a2,a3;a4,a5用点垂公式(2)求出园心、半径,作弧a2a3,a4a5。
(2).以k=tg@,a1,a2用点斜公式(1)求出园心、半径,作弧a1a2。
(3).以直线连接a1a4。
18、犬头(图18)。代码从17000开始。以a1-a3三个点的坐标值定义。三个点是顶点。封闭图形由左侧弧a1a2,右侧弧a1a3和底部直线a2a3组成。左右侧弧a1a2,a1a3在下端点a2,a3处的切线为垂线。生成方法为:
(1).分别关于a1,a2;a1,a3用点垂公式(2)求出园心、半径,作弧a1a2,a1a3。
(2).以直线连接a2a3,a4a3。
19、反犬头(图19)。代码从18000开始。以a1-a3三个点的坐标值定义。三个点是顶点。封闭图形由上下弧a1a3,a1a2和右侧直线a2a3组成。上下弧a1a3,a1a2在右端点a2,a3处的切线为水平线。生成方法为:
(1).分别关于k=0,a1,a2;k=0,a1,a3用点斜公式(1)求出园心、半径,作弧a1a2,a1a3。
(2).以直线连接a2a3。
20、走之尾(图20)。代码从19000开始。以a1-a4四个点的坐标值定义。四个点是顶点。封闭图形由上弧a3a4,右弧a2a3,左直线a1a4,底直线a1a2组成。上弧a3a4在左端点a4处切线为水平线。右弧a2a3在下端点a2处的切线为垂直线。生成方法为:
(1).以k=0,a4,a3用点斜公式(1)求出园心、半径,作弧a3a4。
(2).以a2,a3用点垂公式(2)求出园心、半径,作弧a2a3。
(3).以直线连接a1a4,a1a2。
21、弯头(图21)。代码从20000开始。以a1-a4四个点的坐标值定义。四个点是顶点。封闭图形由左右弧a1a2,a3a4和上下直线a1a4,a2a3组成。左右弧a1a2,a3a4在上下端点a1,a4,a2,a3处的切线分别为垂直线和水平线生成方法为:
(1).分别关于a1、a2;a3,a4用点垂公式(2)求出园心、半径,作弧a1a2,a3a4。
(2).以直线连接a1a4,a2a3。
22、横撇(图22)。代码从21000开始。由a1-a5五个点的坐标值定义。其中三个点a1,a3,a4是顶点,两个点a2,a5是直线与弧的切点。封闭图形由上下曲线a1a2a3,a1a5a4是直线a3a4组成。上下曲线a1a2a3,a1a5a4是直线a1a2,a1a5与弧a2a3,a5a4连于切点a2,a5的线段。生成方法为:
(1).分别关于a1,a2,a3;a1,a5,a4用点垂公式(1)求出园心、半径,作弧a2a3,a5a4。
(2).以直线连接a1a2,a1a5,a3a4。
23、横钩(图23)。代码从22000开始。以a1-a4四个点的坐标值和角度@定义。四个点是顶点。封闭图形由左折线a1a4a3,右弧a2a3和底部弧a1a2组成。左折线a1a4a3是弧a4a3与直线a1a4相连于a4的线段。弧a3a4在a3处的切线为垂线。右弧a2a3在上端点a3处的切线与横轴的夹角为@。底部弧在左端点a1处的切线为水平线。生成方法为:
(1).关于k=tg@,a2,a3用点斜公式(1)求出园心、半径,作弧a2a3。
(2).关于a4,a3用点垂公式(2)求出园心、半径,作弧a4a3。
(3).以k=0,a1,a2用点斜公式(1)求出园心、半径,作弧a1a2。
(4).以直线连接a1a4。
笔素除雨滴点和象牙点外,都是小于笔划的图形。以任一直线与笔素封闭图形相交时,该直线与封闭图形最多有两个交点。
笔素定义中的数值和字定义中的坐标数值都属于NxM的无量纲矩形平面空间(角度值除外),且所有坐标值、数值、N、M都是整数生成宋体字时,先赋予数值一个量纲,如毫米,则数据转而属于NxM毫米的矩形平面空间。再由最终所需字的大小确定比例系数d,并用下式对字定义中的坐标和代码所指的笔素的数值进行比例变换。
R=dxr
x,y,r是定义数据,X,Y,R是实际使用的数据。
以偶对为单元,用新的坐标值为原点,按代码以新数值用上述解析几何的方法生成笔素,便得到了完整的宋体字。
本发明的优点在于:
1、进行比例变换时,没有理论误差,放大和缩小的极限是所用工具的物理极限。
2、所有的字都是由笔素组成,笔素是小于或等于笔划的图形单元。因此笔素的使用频率很高。且基本的图形-笔素只定义一次,因此无冗余数据,从而使数据总量相当少。大致相当于48x48点阵字库数据量的1/3。
3、由于笔素是小于或等于笔划的图形单元,所以笔素组字极为灵活。可以用不同的笔素和不同的字的定义坐标表达宋体字在图形形状和位置上的丰富变化。
实施例:
1、手工制字。按照本方法,任何人都可以求出宋体字的直线和弧的一切参数,用园规、直尺画出这些直线和弧,从而写出美观的各种尺寸的宋体字。手工制字可以在广告业和工程制图中使用。
2、数据机床制字,按照本方法可以求出形成宋体字所需直线和弧的一切参数。以此编制数控机床程序,使刀具没这些直线和弧运动,就加工出各种尺寸的宋体字。例如用数控铣床、线切割机床加工字。
3、电脑成字。可以将本方法所需的数据在电脑中存贮,将本方法编成电脑程序,由电脑求出宋体字的直线和弧的一切参数,根据这些参数用计算机图形学的方法生成直线和弧,便可以使电脑输出宋体字。