2024年5月7日发(作者:)
维普资讯
第29卷第2期 物探化探计算技术 2007年3月
文章编号:1001—1749(2007)O2—0171—06
GOCAD矢量汉字数据库的开发
朱焱辉 ,朱培民2,张英德2
(1.中海油深圳分公司技术部,广州510240;
2.中国地质大学地球物理与空间信息学院,湖北武汉430074)
摘要:为了在地质建模软件GOCAD中实现常用汉字和字符的输入和显示,这里详细阐述了
基于CoreDraw中用VBA编程提取常用汉字轮廓线坐标数据的基本方法,并形成所有汉字矢量
字体表示的数据库。通过GOCAD进行二次开发并在该环境输出矢量汉字。同时还为输入汉字
设计了汉字输入模块,为提取汉字提供了便利条件。实践证明,该方法方便、快捷、实用。
关键词:汉字;GOCAD;CoreDraw;VBA
中图分类号:TP 391.12 文献标识码:A
0前言
1 GOCAD汉字库建立和汉字输入
方案
GOCAD是由法国Nancy大学研制的地质建模
软件。由于该软件在构造和表达三维对象上具有
开发一个汉字字符的矢量字库并实现汉字字
较强的能力,所以常用于地质分界面、地层、断层、
符在GOCAD中的输入和显示软件,需要分四步完
钻井、物化探数据等地质对象的建模和显示上,并
成(见图1):①找出包含所有的第一级、第二级汉
提供了相应的地质分析和解释功能。它是一个在
字中的常用部分,以及英文、数字和标点符号共
地质建模和地质解释中应用相当广泛的软件¨】。
6 851个,将它们存入同一个字符文件中;②利用
CA)CAD软件是英文版,不支持汉字的输入和显示,
CoreDraw软件的二次开发功能,将字符文件中的
即使是GOCAD的工程文件和文件的路径中也不
全部字符转换成实际的字体坐标数据输出;③建立
能含有中文字符,这给实际工作带来了诸多不便。
矢量汉字字符数据库,将步骤②中转换输出的字符
在进行地质建模时,难免会遇到需要显示和输入汉
字体数据存入这个数据库中,形成一个可随时调用
字的地方,例如地质体的名称、地理位置、区域名称
的矢量字库;④利用GOCAD的二次开发功能,使
等都需要进行中文输入和显示。为了解决GOCAD
得开发出的程序能根据用户输入的汉字和字符,从
不能输入和显示汉字的缺陷,需要构造一个实用的
数据库中将对应字符的字体坐标数据取出,然后转
矢量汉字库,并可以任意地进行缩放、平移、旋转等
化成GOCAD的闭合曲线对象,并在GOCAD中显
变换,形成完全的三维汉字。为此,作者在本文中
示出来。
利用CoralDraw绘图软件的字符到曲线的转换功
能,形成GOCAD可以接受的曲线字体对象,解决
了GOCAD汉字输入和显示的问题。在本文中,作
者详细阐述了这种解决方案,通过实践证明,该方
图1程序实现框图
案方便、快捷、实用。
Fig.1 Flow chart of program
收稿日期:2005—11—08
维普资讯
172 物探化探计算技术 29卷
2矢量汉字的提取
CoreDraw是一个优秀的通用绘图软件,它能
将汉字或者字符转换成由汉字或字符轮廓曲线构
成的闭合曲线图形。这种曲线形式的图形与GO—
CAD的曲线图形对象有类似的表示方式,如果把
汉字字符当作曲线对象对待,则可完美地显示到软
件GOCAD中,并且可以任意地进行缩放、平移、旋
转等变换,形成完全的三维汉字。
为了利用CoreDraw提取矢量汉字,作者先将
第一级和第二级常用的6 725个汉字和126个常
用字符(包括英文26个大小写字母,0到9的lO
个数字以及常用的标点和其它符号)代码存人到
文件中;然后把每一个汉字或字符的轮廓曲线的控
制点,全部转换成相对坐标数据,具体过程如下:
(1)在CoreDraw中将汉字和字符转换成闭合
曲线的组合。
(2)将曲线组合图形拆分成单个的闭合曲线
对象。
(3)通过对闭合曲线对象中弯曲的部分进行
插值,然后获得所有曲线对象中的控制点坐标再按
顺序输入到文件,从而实现字符的矢量化。
下面是程序的主要VBA实现代码。
Dim S As Shape ’定义S为图形对象
Dim simplecurve As Curve’定义simple—
curve为曲线对象,创建并显示汉
字,在此以汉字”我”为例
ActiveLayer.CreateArtisticText 0,0,”我”,一
cdrSimpliifedChinese,,”隶书”,100,cdr-
Truc,c ̄Tme,,edrLeftAlignment
ActiveLayer.Shapes(1).ConvertToCurves
’将汉字转化成闭合曲线的组合
ActiveLayer.Shapes(1).BreakApart
’将闭合曲线组合拆分成不同的部分
shapecount=ActiveLayer.Shapes.Count
’获得当前图层中图形(闭合曲线)的数目
’以下代码在闭合曲线的弯曲部分插人
节点,提高字符的显示分辨率
For ii=l To shapecount
dotcount=l
Set S=ActiveLayer.Shapes(ii)
’依次获得图层中的闭合曲线对象
Set simplecurve=S.Curve
scgt ̄ntcount=sir ̄lecurve.Scgr ̄.Count
’得到闭合曲线对象包含段的数目
For iii=l To scgmenteount
eSt scg simplecurve.Segments(dotcount)
’依次得到闭合曲线的每一段
If seg.Type=cdrCurveSegment Then
’判断每一段的曲线类型,如果是
曲线则进入下面的插值程序。
seg.AddNodeAt(O.167)
simplccurve.Segments(dotcount+1).
AddNodeAt(O.2)
simplecurve.Segments(dotcount+2).
AddNodeAt(O.25)
simplecurve.Segments(dotcount+3).
AddNodeAt(0.33)
simplecurve.Segments(doteount+4).
AddNodeAt(0.5)
dotcount=doteount+6
Else
dotcount=dotcount+l
End If
Next iii
Next ii
’为闭合曲线的弯曲部分插人节点的代码结
束
shapecount=ActiveLayer.Shapes.Count
’第二次得到图形的数目
a.writeline(”我”)’输出汉字
a.writeline(CStr(shapecount))
For j=l To shapecount
eSt S=ActiveLayer.Shapes(j)
a.writeline(CS虹(S.Curve.Nodes.Count))
For i=l TO S.Curve.Nodes.Count
x=S.Curve.Nodes(i).PositionX
Y=S.Curve.Nodes(i).PositionY
a.writeline(CStr(x)+””+CStr(y))
Next i
Nextj
ActiveLayer.Shapes.Al1.Dclctc
上面的程序代码①先将S定义为Shape类型
的对象,simplecurve定义为Curve类型的对象;②
然后通过函数CreateArtisticText在当前图层中显示
汉字“我”。汉字是简体中文隶书,字体尺寸为100;
③由于此时图层中只有一个图形,即只有一个
Shape对象,因此可通过获得这个Shape对象,调用
函数ConvertToCurves,并将汉字转换成由曲线组合
的图形;④通过BreakApart将曲线组合图形拆分成
维普资讯
2期 朱焱辉等:GOCAD矢量汉字数据库的开发 173
单个的闭合曲线对象。
I委一 雹_嗣警蠼 墨呲 矗墙●■■E
每个闭合曲线对象由多个节(Segment)组成。
为了对单个闭合曲线中弯曲的节进行插值,需要调
垂0 啊 7
用Shape的属性Count,以获得当前图层中闭合曲
2 1 阿 4
线对象的数目。程序中间部分是对弯曲的节插值
mi 3 2 吖 5
4 3 嗄 7
的部分,插值的方法是通过在一节中均匀地插入五
5 4 腌 9
个节点后实现的。程序的最后一部分是获得所有
节点的( ,y)坐标,并将它们输入到文件,最后调
用Delete方法,删除当前图层中所有的图形对象。
鬻 6T89 56T8 哎锕埃挨 463
以上是将单个的汉字转化成闭合曲线图形的
程序。通过循环的方法就可以将外部字符文件中
图2汉字基本资料表
的所有字符,全部转换成由节点坐标控制的闭合曲
Fig.2 The table of Chinese word data
线对象。
匮蛋 ■ ii●目■;;■●1.睡嗡苗■ 蛙●■■_E一
隧 目目目g目目 目9 ggg目& 硝 gg目目目目g目舞●g目目 目躐 器疆圜藁摹蘸囊—曩曩嚣墨酲曩霪謇鏊
3 矢量汉字数据库的设计与建立
蜀 50 0
26 0 1
27 0 2
为了存储汉字坐标数据,并方便数据地导出,
需要建立适当的数据库,以存储和管理这些数据。
作者在本文中设计的汉字数据库共包括了三个表,
荔 223
分别是“汉字基本资料表”、“汉字闭合曲线编号
32 1
8g01 0 4356
0
33 1 1
表”和“汉字坐标数据表”。
34 1 2
“汉字基本资料表”有四列数据(如图2所
示)。第一列是ID号,其作用主要用于排序;第二
图3汉字闭合曲线编号表
Fig.3 The code table of close llne
列为汉字或字符在数据库中的唯一编号;第三列为
的闭合曲线对象的数目,但却没有对每一个曲线对
具体的汉字或字符;第四列是每一个汉字或字符包
象进行编号。因此,在后二张表中设计了“闭合曲
含闭合曲线的数目。
线编号”,就是为每一个闭合曲线对象进行编号。
“汉字闭合曲线编号表”(如图3所示)的主要
“汉字坐标数据表”(见图4)包含了五列。第
作用是为每一个汉字所包含的闭合曲线对象进行
一
列是ID号,功能与前面二个表相同;第二列“汉
编号。它包括了三列,第一列ID号(作用与汉字
字编号”与“汉字基本资料表”中的汉字编号相同;
基本资料表的ID字段相同);第二列“汉字编号”
第三列“闭合曲线编号”与“汉字闭合曲线编号表”
与图1中的“汉字编号”相对应。虽然在“汉字基
中的“闭合曲线编号”相同。表的最后二列分别记
本资料表”中已经记录下了每个汉字或字符所包含 录了字体轮廓控制点的 、Y坐标。
网 溜瞪驽giC- ̄J E疆 一
疆黼疆鞫 阔鼹爨 露I1.1鞭疆龋骚露圉黼鹱鼹鼹骥 疆蘑 鹱 爨
玉-0 0 .092 1 015 0
2 0 0 .094 .9E.2 0
爨 3 0 0 .095 .902 0
雾
爨
45
6
0
0
0
0
.
.
0
09
96"
8
f .8T
.
36
68
52
0
0
骥 T 0 0 .09B .59l 0
8 0 0 .098 .503i 0
9 0 0 .OgT .422 0
10 0 0 .096 .34B 0
雾 l12l 0 0 .0O954 .28235 0
图4汉字坐标数据表
Fig.4 The coordinate table of Chinese words
维普资讯
l74 物探化探计算技术 29卷
考虑到每种汉字字体矢量字库只有数十兆字
节,上述数据库用ACCESS平台实现。通过以上三
个数据表的建立,将汉字与其对应的坐标联系在一
起,方便了后续程序对汉字的访问与数据导出。三
张表的矢量汉字字体数据,可以用前述的代码,略
加改变,直接输出到这些表中即可。
汉字中每一个闭合曲线对象的编号(见图3)。
strSq1.Format(”select from汉字闭合曲线编
号表where汉字编号= %s,,,,m_ChineseCode);
//构造SQL语句
m
_
pReeordset一
.
>Open(一variant—t(strSq1),in—pConnection.Get—
InterfacePtr(),adOpenDynamic,adLockOptimistic,
adCmdText);
4汉字输入与GOCAD汉字曲线对
象的形成方法
在GOCAD中的汉字显示与其它图形处理软
件中的汉字显示有类似的方式和特点,除了可以输
入汉字或字符外,还需要满足用户对字体、尺寸
(放大倍数)、字间距、排列方式等的显示要求。为
此,在本文中特别设计了满足这些要求的汉字输入
的程序界面(如图5所示)。
图5汉字输出程序界面
Fig.5 The output platform of Chinese words
要实现汉字的输人,第一步是根据用户输人的
汉字,从“汉字基本资料表”中找出汉字对应的唯
一
编号(见图2)。具体代码(C++)实现是:
strSq1.Format(”select木from汉字资料表
where汉字= %Sm,re_Chinese);
m
_
pRecordset——
>Open(一variant_t(st ̄Sq1),in—pConnection.
GetInterfacePtr(),adOpenDynamic,adLock・
Optimistic,adCmdText);var:in—pRecordset
一
>GetCollect(”汉字编号”);
m
_
ChineseCode:(LPCSTR)(_bs )vat;
其中,in—pRecordset是一ReeordsetPtr类型的指
针;m_pConnection ̄_ConnectionPtr类型的指针。
上面的程序通过构造一个SQL语句,利用打
开满足SQL语句的记录集,从记录中通过取出汉
字所对应的唯一编号赋给一variant—t类型的变量
var,最后将var强制类型转换成CString类型,并赋
给变量m_ChineseCode。
程序实现的第二步是根据找出的汉字编号in—
ChineseCode,再从”汉字闭合曲线编号表”中获取
//打开满足SQL语句条件的记录集
linecount=m
_
pRecordset一>RecordCount;
//获得汉字中闭合曲线对象的数目
m
_
LinePartCode=new CString[1inecount];
for(1ong i=0;i<linecount;i++)
{ var=in—pRecordset一>GetColhet(”闭
合曲线编号”);//获得闭合曲线对象
编号
m
_
LinePartCode[i]=(LPCSTR)(一bstr~
t)vat; //强制类型转换
m
_
pRecordset一>MoveNext();}
//移到下一条记录
以上程序将汉字闭合曲线对象的编号存人
CString类型的m_LinePartCode数组中。
程序实现的第三步是获取汉字每一闭合曲线
对应点的坐标。下面的代码实现了从数据库中取
出单个汉字或者字符所有控制点的坐标,并分别存
人三个数组中。具体如下:
strSq1.Format(”select from汉字坐标数
据表where汉字编号= %S ,m_ChineseCode);
//构造SQL语句
m
_
pRecordset——
>Open(一varinat—t(st ̄Sq1),in—pCon—
nection.GetInterfacePtr(),adOpcnDynamic,adLock—
Optimistic,adCmdText);
//打开记录集
m
_
pRecordset一>Sort=”ID ASC”:
//用于按照ID号排序
recordcount=m
—
pRecordset一>Record—
Count; //获得每个汉字在数据库中包含记录的
数目
lfoat木x
木z
,
木Y
,
;
//定义三个数组用于存放所有闭合曲线
对象的X,Y,z坐标
CString m
_
Code:
//用于存放所有闭合曲线编号
维普资讯
2期 朱焱辉等:GOCAD矢量汉字数据库的开发 175
x=new float[recordcount];Y=new float
{/ m_Zoom表示图5中用户输入的放
[recordcount];z=new lfoat[recordco吼t];
大倍数,m_Xeord,m_Ycord,m_Zcord表示用户输
m
_
Code=new CString[reeordeount];
入的x、Y、z的起始坐标,x_move和y_move是与
for(1ong j=O;j<recordcount;j++)
字体排列方式和汉字间距有关的变量 /
//读出编号和坐标数据
xx[k]=m_XCodr+(x[i] m—Zoom)+
{ vat=m—pReeordset一>GetColleet(”
闭合曲线编号”);
yy[k]=m_YCord+(Y[i] m_Zoom)+y
m
—
Code[j]=(LPCSTR)(一bstr—t)
_
move;ZZ[k]=m_ZCord+Z[i];k++;}
vat";
else
vat"=m
pReeordset一>GetColleet
_
(”x”);x[j]=float(var.fltVa1);
//表示同一个闭合曲线对象的坐标点已经判断完
毕,然后调用生成GOCAD闭合曲线对象的函数。
vat"=m
_
pReeordset一>GetColleet
(”Y”);Y[J]=float(vat".fltVa1);
{mypline.GOCADP ̄ne(强,YY,zz,k);k=O;
ak;}
vat"=m
_
pReeordset一>GetColleet
bre
(”z”);z[j]=float(vat".fltVa1);
if(I==recordcount一1)//表示一个汉字
m
pReeordset一>MoveNext();}
的最后一个闭合曲线对象
_
//移动到下一记录
{mypline.GOCADP ̄ne(强,YY,zz,k);k=0;
m
_
pReeordset一>Close();
break;}
//关闭记录集
}} .
程序实现的第四步是将每一个闭合曲线以及
以上四步程序组合到一起,通过循环的方式可
它们的控制点全部分开,成为单个的闭合曲线对
以将用户输入的所有汉字和字符一起生成GOCAD
象,再调用生成GOCAD闭合曲线对象的函数,完
的一个闭合曲线对象文件,然后调用MyPLine的成
成数据的转换。
员函数GOCADSave()将数据存储到磁盘上。
上面的程序中用到的MyPLine变量是用GO—
lfoat xx, YY, zz; //用于存放每个闭合
CAD的标准线对象类Pline来定义的。Pline类主
曲线对象控制点坐
要包括三个函数:GOCADCrea ̄ne、GOCADPLine
标
和GOCADSave。
xx=new float[reco ̄count];yy=new float
程序实现的第五步是:在GoCAD中,为了将
[reco ̄count];ZZ=new float[record—
汉字控制点坐标数据转化成闭合曲线对象,首先需
count];
要将控制点坐标数据转化成GOCAD的空间点
//reeordeount表示每个汉字在数据库中
Point3d对象;然后由Point3d对象构造原子Atom;
.
包含记录的目
再由原子Atom对象构造节segment对象;最后将
i=0;k=0;mypline.GOCADCrea ̄Une(out一
所有的节segment连接起来,构成GOCAD的闭合
¥avenalne);//mypline是MyPLine类型的变量out-
曲线对象。下面是C++代码实现。
¥avenalne是输出文件名,MyPLine是
ILine iline;PLne pline
对GOCAD进行开发产生的新类
_
tmp;SegUse
for(j=O;j<linereeordeount;j++)
・segment=nil;PtrList<SegUse>segs;
{ //linereeordeount表示每个汉字所包
PtrList<ILine> ilines;
含的闭合曲线对象的数目
pline
_
tmp=pline::create(savename);
ofr(;i<recordcount;i++)
//创建Pline对象
{if(m—Code[i]==m—LinePartCode
iline=pline
_
tmp一>create_element();
[j])
//由Phne对象创建一个Iline
/ 如果第i个坐标点所对应的闭合曲线对象编号
对象
与第j个闭合曲线对象编号相同,即这些坐标点都
Point3d point=new Point3d[Number];
属于同一个闭合曲线对象,则将这些点的坐标连同
//定义三维空间点数组
放大倍数以及其它参数重新存入新的数组中。 /
Atom atoms=new Atom 『Number]:
维普资讯
176 物探化探计算技术
//定义原子即含有属性的三
维空间点
29卷
for(1ong i=0;i<Number;i++){
//给三维空间点和属性数组
赋值
・point[i]=Point3d(float(x[i]),float(Y
[i]),lfoat(z[i]));//由坐标构造GOCAD的空
间点对象
atoms[i]=iline一>create—atom(point
[i]); //用于构造出原子
}
for(1ong i=1;i<Number;i++){
//调用ILine的成员函数由原
子构造节对象(segment)
segment=iline一>create
_
一
图6一个汉字字符串在GOCAD软件中四种字体的
显示对比结果
Fig.6 The output result of Chinese words in GOCAD
simplex(atoms[i
5结论
为了在GOCAD地质建模软件中实现三维汉
1],atoms[i]);
}
segment=iline一>create
—
simplex(atoms[Num—
ber一1],atoms[0]);//将Iline起始点连起来构成
闭合曲线对象
segs.append(segment);
//将节对象添加到节对象列
表中
以上程序将汉字中单个的闭合曲线对象用
GOCAD的Segment表示出来,然后将该节对象添
加到节列表segs中,通过循环的方式就能将所有
汉字的所有闭合曲线对象以sement的形式添加 g
到节列表segs中,用于最终构成GOCAD的PLine
对象pline—tmp。
程序实现的第六步是将前述程序形成的汉字
字体轮廓曲线保存,形成GOCAD能够接受的对象
文件。代码如下
pline
tmp一>init(segs,ilines,re,e);
//由节对象列表segs生成PLine的
_
字的显示,作者在文中提出的利用CoreDraw绘图
软件提取矢量汉字,建立矢量汉字数据库,并将之
在GOCAD中输入和显示的方案是成功的。实际
上,上述汉字的实现方案,完全可以移植到一些只
能在工作站上运行的大型图形处理和三维可视化
软件上。
参考文献:
[1] 朱焱辉,朱培民,金丹.从&reGis平面栅格图形到
GOCAD三维图像转换的开发探讨[J].工程地球物
理学报,2004,l0(5):435.
[2]张立科.Visual C 6.0数据库开发技术与工程实
践[M].北京:人民邮电出版社,2004.
[3]李村合.VC 应用程序中ODBC数据源的自动注
册[J].物探化探计算技术,2003,25(1):88.
[4] 张丽莉,吴健生,王家林.地学数据文件向Shapefile
文件的转换[J].物探化探计算技术,2004,26(1):
78.
对象pline_tmp
GObj group=(GObj )pline—tap;r
//将Pnne的对象指针强制转换成
[5]冯德山,戴前伟.用Visual C
231.
开发地质雷达正演
模拟软件[J].物探化探计算技术,2004,26(3):
[6]汤彬,陆玲.用VC开发Windows字符曲线类[J].
物探化探计算技术,2000,22(3):282.
[7]陈志远,赵程.VC环境下AutoCAD图形实体的二次
C,obj类型的指针
gobj::save(group);
//调用Gobj的成员函数保存数据
前述的六步程序,完整实现了将用户输入的汉
字或者字符串显示在GOCAD软件的过程。图5
和图6是一个用户输入“中华人民共和国”的汉字
字符串,并在GOCAD中显示出四种字体对比结果
的例子。
开发[J].现代制造工程,2006,8:54.
作者简介:朱焱辉(1979一),男,汉族,四川泸州
人,硕士,主要研究方向:地球探测与信息技术。
发布评论