[0022]所謂寬度漸變,就是指隨著線的走向,線的寬度不斷發(fā)生連續(xù)性的變化。在線寬不斷變化的情況下,還需要對(duì)矢量線要素進(jìn)行符號(hào)填充。所以符號(hào)的顏色結(jié)構(gòu)表信息實(shí)際上控制了最終的顏色,而寬度漸變函數(shù)控制在什么寬度范圍內(nèi)填充顏色。
[0023]如圖2所示,一個(gè)符號(hào)的顏色結(jié)構(gòu)表信息按照整個(gè)符號(hào)的寬度SymbolLength,整個(gè)符號(hào)有多少列CoIumnCount,每一列有多少行CoIumnRowCountArray,每一列的寬度ColumnWidthArray,每一行的高度RowHeightAr ray 和每一個(gè) Cel I 的顏色 Cel IColorTable 來組織。基于這個(gè)符號(hào)顏色結(jié)構(gòu)表,可以在Shader中根據(jù)每一個(gè)像素的U-V值,從顏色表中取值來進(jìn)行矢量線要素的填充。
[0024]根據(jù)每個(gè)像素的U-V值還能夠確定其距離起始頂點(diǎn)的距離,利用這個(gè)距離和整個(gè)矢量線的長(zhǎng)度相除,得到在U方向上的比例值。根據(jù)這個(gè)比例值,結(jié)合最大線寬和最小線寬,即可確定當(dāng)前像素相應(yīng)的寬度。利用公式w’ =Width2+(Widthl_Width2)*(MaxU-u’ )/MaxU能夠計(jì)算出這個(gè)寬度。將這個(gè)公式映射到Shader程序中,用Scalel和Scale2分別表示最大寬度的縮放系數(shù)和最小寬的縮放系數(shù),再依據(jù)同構(gòu)的公式:S = SCale2+(SCalel-SCale2)*(MaxU-u’)/MaxU計(jì)算得到當(dāng)前像素的寬度縮放系數(shù)。如圖3所示。
[0025]利用這個(gè)縮放系數(shù),構(gòu)建相反的擴(kuò)張系數(shù)Expans1nFactor (EF),也就是EF= 1/S。這樣可以將原始的V值在垂直方向上進(jìn)行拉伸,使得最終需要填充的范圍仍然集中于0-1的范圍,但是實(shí)際寬度發(fā)生了縮放。計(jì)算半擴(kuò)張系數(shù)HalfExpans1n(HE),HE= (EF-l)/2,這樣可以使V值依據(jù)中央擴(kuò)張。根據(jù)HE計(jì)算得到最后的V值:V(p) =V ’*EF-HE; v ’是原來的V值,V(P)是縮放后的V值。如圖4(a)所示,經(jīng)過這種拉伸-縮放的計(jì)算之后,V值被確定在當(dāng)前線寬范圍內(nèi)。在Shader中,需要定義IsWidthScale變量來指定當(dāng)前繪制模式是否是要進(jìn)行漸變線寬的繪制;需要定義Scalel和Scale2來傳遞最大線寬參數(shù)和最小線寬參數(shù)。
[0026]本發(fā)明技術(shù)方案的具體說明如下:
[0027]A.首先遍歷線要素中的每一個(gè)頂點(diǎn),按照半個(gè)最大線寬向兩邊擴(kuò)展,由此可以將一個(gè)線段擴(kuò)展成一個(gè)矩形;利用矩形的四個(gè)頂點(diǎn),組合生成相應(yīng)的兩個(gè)三角形;由一系列連續(xù)的線段可以生成連續(xù)的三角形集合。對(duì)于沿著線走向,往左邊擴(kuò)展出來的頂點(diǎn),設(shè)定其V值為O;而往右邊擴(kuò)展出來的頂點(diǎn),設(shè)定其V值為I。左右兩邊的擴(kuò)展頂點(diǎn)的U值計(jì)算,是根據(jù)擴(kuò)展頂點(diǎn)對(duì)應(yīng)的線上的點(diǎn)與線的起始點(diǎn)計(jì)算長(zhǎng)度,用長(zhǎng)度除以最大線寬得到左右擴(kuò)展頂點(diǎn)的U值。
[0028]B.對(duì)于需要沿線重復(fù)填充的符號(hào)單元,該符號(hào)首先從橫向上被分為寬度一致的幾列,對(duì)每一列再分為顏色一致的幾行。不同列的寬度可以不同,但每一列中的每一行寬度相同;列中的不同行的顏色可以不同,但一行只能有一個(gè)顏色。由這些列-行(Column-Row)構(gòu)成了一系列的單元(Cel I)。每個(gè)Column被賦予寬度屬性和行數(shù)屬性,每個(gè)Row被賦予高度屬性,每個(gè)Cell被賦予顏色值,整個(gè)符號(hào)顏色結(jié)構(gòu)表被賦予總列數(shù)、總寬度和總高度屬性。
[0029]C.通過GPU可編程流水線,將構(gòu)造好的線三角網(wǎng)Mesh、需要繪制的符號(hào)顏色結(jié)構(gòu)信息傳遞到Shader程序中。
[0030]D.在所設(shè)計(jì)的Shader程序中,根據(jù)三角網(wǎng)Mesh頂點(diǎn)上的U-V值,可以利用GPU內(nèi)置的光柵化方法得到每個(gè)像素的U’值(即該像素在水平方向上到線起點(diǎn)的距離)和V’值(即該像素在垂直方向上到線的上邊界的距離)。利用這個(gè)U’值,和相應(yīng)的寬度漸變函數(shù),計(jì)算得到新的U(P)值;這個(gè)U(P)值可能大于I,也可能小于0,在后續(xù)過程中只有0-1之間的像素才會(huì)被填充顏色,否則設(shè)置為透明色。
[0031]D.在所設(shè)計(jì)的Shader程序中,根據(jù)前面計(jì)算得到的U(p)值和V’值。利用這個(gè)U(p)值,首先去掉當(dāng)前像素之前的所有符號(hào),也就是將U值映射到單個(gè)符號(hào)的坐標(biāo)系中;用公式U’(P) =U(P)-SLX [U(p)/SL],可以得到當(dāng)前像素距離符號(hào)最左側(cè)的距離U’(P);其中SL是符號(hào)的總寬度,[U(p)/SL]是對(duì)U(p)/SL的值進(jìn)行取下整數(shù)。由此可以得到當(dāng)前像素處于顏色結(jié)構(gòu)表中具體哪一個(gè)Cel I。
[0032]E.在GPU中用利用計(jì)算得到的Cell的顏色或者透明色對(duì)矢量線要素進(jìn)行逐像素填充,得到最后的寬度漸變繪制結(jié)果。
[0033]實(shí)施例:
[0034]相比于傳統(tǒng)計(jì)算機(jī)可視化領(lǐng)域中的直線繪制,由于地圖符號(hào)的復(fù)雜性,地圖矢量線要素的繪制更為困難;傳統(tǒng)的用多條寬度不一的線來擬合漸寬線的繪制,難以滿足地圖繪制的要求,也造成了空間信息傳遞的丟失。所以本發(fā)明設(shè)計(jì)了一種基于GPU Shader的寬度漸變線型地圖符號(hào)繪制方法,來適應(yīng)于不同地圖符號(hào)的漸寬繪制。如圖5,四種典型的寬度漸變線型地圖符號(hào)和其應(yīng)用于矢量線要素繪制的效果。
[0035]下面是用軟件方法,在C++語言和OpenGL環(huán)境下,實(shí)現(xiàn)基于GPUShader的寬度漸變線型地圖符號(hào)的繪制:
[0036](I)定義結(jié)構(gòu)體SymbolStructure表不符號(hào)結(jié)構(gòu):
[0037]#define MAX—COL—NUM 16//最多多少列
[0038]#define MAX—ROW—NUM 16//最多多少行
[0039]struct CellColor{f1at r;f1at g;f1at b;float a;}
[0040]struct SymboIStructure
[0041]{
[0042]int uiUseColNum;//一共有多少列
[0043]float UfUseColWidth;//整個(gè)符號(hào)的寬度
[0044]int uiUseRowNum[MAX—COL—NUM];//每一列有多少行
[0045]float ufColWidth[MAX—COL—NUM];//每一列的寬度
[0046]int u i Co I Ty pe [ MAX_C0L_NUM ];//每一列是否為背景列的標(biāo)志
[0047]float ufRowHeight[MAX—COL—NUM][MAX—ROW—NUM];//每一行的高度
[0048]CellColor uf4CellColorl[MAX_C0L—NUM][MAX—ROW—NUM];//顏色表
[0049]float ufMaxULength; //最大的U值
[0050]int UiUseScaleV;//是否進(jìn)行沿線走向的漸寬繪制,0表示否,I表示是
[0051]float UfScaleVl;//最大線寬系數(shù)
[0052]float ufScaleV2;//最小線寬系數(shù)
[0053]}
[0054](2)在Shader中定義一組變量用于傳遞符號(hào)顏色結(jié)構(gòu)表信息:
[0055]#define MAX—COL—NUM 16//最多多少列
[0056]#define MAX—ROW—NUM 16//最多多少行
[0057]varying float vfU;//由頂點(diǎn)U值傳遞過來的u’值
[0058]varying float 乂:[7;/7由頂點(diǎn)1]值傳遞過來的11’值
[0059]uniform int uiUseColNum;//—共有多少列
[0060]uniform float ufUseColWidth;//整個(gè)符號(hào)的寬度
[0061]uniform int uiUseRowNum[MAX—COL—NUM];//每一列有多少行
[0062]uniform float ufColWidth[MAX—COL—NUM];//每一列的寬度
[0063]uniform float ufRowHeight[MAX—COL—NUM*MAX