線切割機(jī)實(shí)現(xiàn)切割漢字的自動(dòng)編程技術(shù)
1 引言 隨著現(xiàn)代計(jì)算機(jī)和控制技術(shù)的發(fā)展,人們?yōu)榫€切割機(jī)裝備了基于PC機(jī)且功能愈來(lái)愈強(qiáng)大的編程和控制系統(tǒng),使線切割機(jī)的應(yīng)用技術(shù)不斷有新的發(fā)展。編程控制系統(tǒng)的發(fā)展是線切割加工技術(shù)發(fā)展的一個(gè)重要方面。對(duì)編程系統(tǒng)來(lái)講,先是通過專用語(yǔ)言對(duì)待加工零件進(jìn)行描述,然后轉(zhuǎn)化為切割指令實(shí)現(xiàn)自動(dòng)編程,后又把CAD技術(shù)引入編程中,從而實(shí)現(xiàn)了圖形式輸入方式,大大提高了編程效率和質(zhì)量;在控制技術(shù)上,則從早期的開環(huán)控制過渡到了檢測(cè)多個(gè)加工狀態(tài)參數(shù)的自適應(yīng)控制系統(tǒng)乃至模糊控制系統(tǒng)。 但直到現(xiàn)在,線切割機(jī)的應(yīng)用范圍還主要限制在機(jī)械零部件及模具的加工上,在線切割機(jī)上實(shí)現(xiàn)切割漢字可以說是一個(gè)空白。針對(duì)我國(guó)的國(guó)情,實(shí)現(xiàn)對(duì)漢字的切割既有現(xiàn)實(shí)的市場(chǎng)需求,又有廣闊的應(yīng)用前景。 在線切割機(jī)上進(jìn)行加工,首先要通過編程系統(tǒng)將待加工零件轉(zhuǎn)化為切割指令。為此要實(shí)現(xiàn)切割漢字的功能,也必須將要切割的漢字字形輪廓轉(zhuǎn)化為切割指令。本文將從幾個(gè)方面具體講述在Windows操作系統(tǒng)的PC平臺(tái)上,從TrueType字庫(kù)中提取漢字字形輪廓,并將其轉(zhuǎn)化為切割指令的自動(dòng)編程技術(shù)。 2 字形輪廓的提取 要實(shí)現(xiàn)切割漢字首先要獲得漢字字形輪廓,這涉及到如何從字庫(kù)中提取漢字字形輪廓的問題。漢字的字體根據(jù)其實(shí)現(xiàn)形式的不同可分為點(diǎn)陣字體、矢量字體及TrueType字體等幾種。其中使用最廣泛的為TrueType字體,與其他字體相比,TrueType字體具有明顯的優(yōu)點(diǎn): (1)它使用直線和曲線對(duì)字符進(jìn)行描述,具有放大和縮小不變形的特點(diǎn); (2)具有處理速度快及與設(shè)備無(wú)關(guān)的特點(diǎn); (3)它是Windows系統(tǒng)所使用的最廣泛的字體,因而Windows提供了大量的API函數(shù)來(lái)支持和處理這種字體,利用這些函數(shù)可方便地對(duì)TrueType字符進(jìn)行各種處理,如旋轉(zhuǎn)、變形等。 在TrueType字體中,字形輪廓是由一些直線和曲線的集合及一些對(duì)字體的描述信息所組成,這些直線和曲線定義了TrueType字體及符號(hào)的外形輪廓,而那些字體的描述信息則用來(lái)控制和調(diào)整直線的長(zhǎng)度和曲線的形狀,主要用來(lái)調(diào)整字形輪廓尺寸,使用這些描述信息可對(duì)TrueType字體或符號(hào)在保持其原始形狀的情況下進(jìn)行放大、縮小等處理。 Windows提供了許多函數(shù)來(lái)處理TrueType字體,其中與提取字形輪廓有關(guān)的最主要的函數(shù)為GetGlyphOutline,它可用來(lái)提取被選擇到指令設(shè)備環(huán)境(如內(nèi)存、顯示設(shè)備等)的字符的輪廓或位圖。在Windows API中,GetGlyphOutline函數(shù)聲明如下: DWORD GetGlyphOutiline( HDC hdc,∥設(shè)備環(huán)境的句柄 UINT uChar,∥所要查詢的字符 UINT uFormat,∥所要返回的數(shù)據(jù)類型 LPGLYPHMETRICS lpgm,∥指向字符規(guī)格結(jié)構(gòu)的地址 DWORD cbBuffer,∥數(shù)據(jù)緩沖區(qū)的大小 LPVOLD lpvBuffer,∥數(shù)據(jù)緩沖區(qū)的地址 CONST MAT2*lpmat2,∥變換矩陣結(jié)構(gòu)的地址); 其中的主要參數(shù)說明如下: uChar:指定所要查詢的字符,對(duì)漢字來(lái)說是指漢字的編碼,如:GB-2312和Unicode等編碼。 uFormat:指定函數(shù)所要提取的數(shù)據(jù)的格式,可取下面一些值:GGO_ITMAP、GGO_NATIVE、GGO_METRICS、GGO_GRAY2_BITMAP、GGO_GRAY4_BITMAP、GGO_GRAY8_BITMAP。 對(duì)于提取字符的字形輪廓來(lái)說,由于只需得到字形輪廓的二值圖象,不用得到灰度圖象,因此uFormat參數(shù)可取兩個(gè)值:GGO_BITMAP、GGO_NATIVE。如取GGO_BITMAP,函數(shù)將返回字符的字形輪廓位圖;取GGO_NATIVE,函數(shù)將返回用來(lái)描述字符外形輪廓的曲線的點(diǎn)的數(shù)據(jù),使用的單位是字體設(shè)計(jì)的單位,如uFormat參數(shù)取值為GGO_NATIVE,則任何lpmat2參數(shù)指定的變換矩陣將被忽略。由于可能需對(duì)提取出的字形輪廓作一定的變換處理(如:放大、縮小、旋轉(zhuǎn)及改變縱、橫比等),將參數(shù)uFormat的值設(shè)置為GGO_NATIVE。 調(diào)用GetGlyphOutline,函數(shù)將返回一系列的折線和樣條曲線,返回的折線和曲線的信息存儲(chǔ)在一個(gè) TTPOLYGONHEADER結(jié)構(gòu)及緊隨其后的多個(gè)TTPOLYCURVE結(jié)構(gòu)中,這些信息主要為描述折線和曲線所需的點(diǎn)的坐標(biāo),要描述字形輪廓須使用這些信息。上述兩個(gè)結(jié)構(gòu)中所有的點(diǎn)都以POINTFX結(jié)構(gòu)形式返回,這些點(diǎn)描述的是絕對(duì)位置而不是相對(duì)位置。要描繪一個(gè)TrueType字符的字形輪廓,須同時(shí)使用折線和曲線。TTPOLYGONHEADER結(jié)構(gòu)中的pfxStart成員返回字形的封閉輪廓的起始點(diǎn),也是封閉輪廓的終止點(diǎn)。 下面對(duì)其中幾個(gè)重要的數(shù)據(jù)結(jié)構(gòu)作簡(jiǎn)要的說明。 其中,TTPOLYGONHEADER結(jié)構(gòu)指定一個(gè)TrueType字符的字形輪廓的起始點(diǎn)及該輪廓的類型(直線或曲線)。其定義為: typedef struct_TTPOLYGONHEADER{//ttph DWORD cb; DWORD dwType; POINTFX PfxStart; }TTPOLYGONHEADER,FAR.LPTTPOLYGONHEADER; 其中成員cb指定描述字形輪廓的TTPOLYGONHEADER結(jié)構(gòu)和TTPOLYCURVE結(jié)構(gòu)所需的字節(jié)數(shù);dwType字符的輪廓類型;pfxStart指定輪廓的起始點(diǎn)。 TTPOLYCURVE結(jié)構(gòu)中包含了TrueType字符中有關(guān)字形輪廓曲線的信息。其定義為: typedef struct tagTTPOLYCURVE { // ttpc WORD WType; WORD Cpfx; POINTFX apfx [1]; } TTPOLYCURVE,FAR*LPTTPOLYCURVE; 其中成員wType指定TTPOLYCURVE結(jié)構(gòu)所描述的曲線類型,可有兩個(gè)取值;TT_PRIM_LINE和TT_PRIM_OSPLINE,分別代表曲線是折線和B樣條曲線;cpfx指定數(shù)組中POINTFX結(jié)構(gòu)的數(shù)目;apfx指定一個(gè)確定折線或者B樣條曲線的POINTFX結(jié)構(gòu)類型的數(shù)組。 POINTFX結(jié)構(gòu)中包含用來(lái)描述TrueType字符字形輪廓的點(diǎn)的坐標(biāo),其定義為: typedef struct tagPOINTFX { // ptfx FIXED X; FIXED Y; } POINTFX, 其中X和Y分別代表點(diǎn)的橫、縱坐標(biāo)。 在調(diào)用GetGlyphOutline函數(shù)得到描述字形輪廓的數(shù)據(jù)后,要將其描繪出來(lái)還需調(diào)用繪制直線和曲線的函數(shù)。一個(gè)TrueType字符由折線和二次樣條曲線描繪而成,調(diào)用GetGlyphOutline函數(shù)返回了描繪這些折線和曲線所需的點(diǎn)的有關(guān)信息,這些信息存儲(chǔ)在TTPOLYGONHEADER和TTPOLYCURVE結(jié)構(gòu)中,根據(jù)其中的成員wType所指定的不同值,來(lái)調(diào)用Windows API所提供的相關(guān)繪制折線和樣條曲線的函數(shù),即可繪制出字符的字形輪廓。在繪制時(shí)還可根據(jù)需要對(duì)字形輪廓進(jìn)行各種處理,如放大、縮小、旋轉(zhuǎn)及改變字符的縱橫比等。圖1顯示了采用以上方法提取的“電”字的字形輪廓。 圖1 “電”字的字形輪廓 還有一個(gè)需解決的問題是如何獲得漢字編碼的問題。通常漢字是以字符串的形式輸入計(jì)算機(jī)的,要調(diào)用GetGlyphOutline函數(shù)得到某一漢字的字形輪廓,還須得到該漢字的編碼(一般指GB-2312編碼,在Windows NT和Windows 2000下可使用Unicode編碼),用來(lái)指定GetGlyphOutline函數(shù)中的uChar參數(shù),這就需進(jìn)行由字符串到漢字編碼的轉(zhuǎn)換。下面給出了用Delphi實(shí)現(xiàn)的由漢字字符串到漢字的GB-2312編碼的轉(zhuǎn)換函數(shù),該函數(shù)的輸入?yún)?shù)為字符串的形式的單個(gè)漢字,返回值為輸入?yún)?shù)漢字的GB-2312編碼。 圖2 未經(jīng)編輯處理時(shí)線切割機(jī)所能加工的“電”字字形輪廓 圖3 編輯處理后線切割機(jī)所能加工的“電”字字形輪廓 因?yàn)槲覀冎恍铇?biāo)識(shí)字形的邊界輪廓,因此將其轉(zhuǎn)化為二值圖象即可。將字形輪廓轉(zhuǎn)化為二值圖象,也就是將其轉(zhuǎn)化為一個(gè)用矩陣表示的象素點(diǎn)圖象,矩陣中的每一位都是二進(jìn)制數(shù),當(dāng)該位為1時(shí)表示字符的筆劃經(jīng)過此位,該位為0時(shí)表示字符的筆劃不經(jīng)過此位。因?yàn)橹灰直娉瞿滁c(diǎn)為0還是1,因此每個(gè)點(diǎn)只要用一位二進(jìn)制數(shù)表示即可,這樣1個(gè)字節(jié)就可以表示8個(gè)象素點(diǎn),但為方便敘述本文采用以1個(gè)字節(jié)表示1個(gè)點(diǎn)來(lái)進(jìn)行說明。 |