摘 要: 縮放是OpenGL三維模型展示的基本操作之一,,一般縮放時(shí)由于整個(gè)場(chǎng)景圍繞視景體中心縮放,感興趣區(qū)域在視圖窗口中的位置會(huì)不斷變化甚至離開(kāi)視景體,,需要不斷地執(zhí)行平移操作,,不斷地修正感興趣區(qū)域在視圖窗口中的位置,無(wú)法集中精力觀察工程計(jì)算中模型的變化細(xì)節(jié),。為了解決該問(wèn)題,,從圖形學(xué)角度提出了一種改進(jìn)的局部縮放算法,實(shí)現(xiàn)了用鼠標(biāo)滾輪縮放模型時(shí),,鼠標(biāo)選擇處的模型不離開(kāi)視景體而相對(duì)視圖窗口的位置保持不變,,省去了傳統(tǒng)算法中用戶進(jìn)行縮放操作時(shí)需要不斷進(jìn)行平移的操作,改進(jìn)了用戶體驗(yàn),。該算法在多個(gè)可視化項(xiàng)目中得到實(shí)際應(yīng)用,,取得了很好的操作體驗(yàn)。
關(guān)鍵詞: 計(jì)算機(jī)應(yīng)用,;坐標(biāo)變換,; 局部縮放;可視化,;視景體
OpenGL是一個(gè)與硬件平臺(tái)無(wú)關(guān),、與系統(tǒng)平臺(tái)無(wú)關(guān)的三維圖形庫(kù),其在三維真實(shí)感圖形制作中具有優(yōu)秀的性能,已經(jīng)成為高性能的圖形和交互視景處理的標(biāo)準(zhǔn),。OpenGL API由200多個(gè)函數(shù)組成,,主要提供圖形繪制、變換操作,、顏色模式,、光照、圖像效果增強(qiáng),、位圖和圖像、紋理映射,、交互與動(dòng)畫(huà)8個(gè)方面的功能,。一些跨平臺(tái)的三維庫(kù)(如OSG)也是建立在OpenGL之上的,對(duì)OpenGL的API進(jìn)行了封裝,,利用這些三維庫(kù),,開(kāi)發(fā)人員可以開(kāi)發(fā)豐富的交互式應(yīng)用程序[1-3]。GPU高性能計(jì)算的支持,,使得OpenGL開(kāi)發(fā)的三維程序運(yùn)行更加流暢,、場(chǎng)景更加逼真[4]。
OpenGL具有強(qiáng)大的圖形處理功能,,包括圖形的平移,、旋轉(zhuǎn)、縮放等,。靈活運(yùn)用OpenGL的這些功能,,可以實(shí)現(xiàn)很多更復(fù)雜的操作。但在一般情況下,,當(dāng)利用OpenGL進(jìn)行圖形的縮放時(shí),,往往是以視景體的中心為縮放中心進(jìn)行整體縮放[5],該算法雖然在整體上實(shí)現(xiàn)了一定的縮放功能,,但縮放的過(guò)程中,,用戶期望的縮放區(qū)域會(huì)在Windows視圖窗口中不斷變化甚至離開(kāi)視景體。以放大為例,,為了觀察感興趣區(qū)域的細(xì)節(jié),,如模型在外力作用下的變化過(guò)程,往往需要借助平移將目標(biāo)區(qū)域移到合適位置后才能繼續(xù)放大,,在放大達(dá)到一定系數(shù)時(shí),,放大-平移的操作非常頻繁,嚴(yán)重影響了操作體驗(yàn),。參考文獻(xiàn)[6]提出了一種拉框放大算法,,計(jì)算鼠標(biāo)框選區(qū)域在視景體中的位置,然后將這個(gè)位置重新投影到視口上,該算法雖然能夠?qū)崿F(xiàn)放大,,但是不能夠局部縮小,,且放大與縮小操作的切換不連貫。本文提出的算法不僅能夠?qū)崿F(xiàn)局部縮放的效果,,而且在操作方法上也作了改進(jìn),,用戶滾動(dòng)鼠標(biāo)的滾輪,默認(rèn)以光標(biāo)處的模型為感興趣區(qū)域中心,,縮放將圍繞該中心進(jìn)行,,而且用戶期望的縮放區(qū)域在視景體中原地縮放,縮小和放大操作切換流暢,。
1 OpenGL變換的基本原理
三維模型顯示到二維屏幕的過(guò)程分為造型變換,、取景變換、投影變換和視口變換4個(gè)階段[7],,如圖1所示,。
其中,方框中為坐標(biāo)變換名稱,,箭頭上為坐標(biāo)系名稱,。
造型變換將各個(gè)處于自身局部坐標(biāo)系中的模型變換到世界坐標(biāo)系中組成整個(gè)場(chǎng)景;取景變換將定義在世界坐標(biāo)系下的場(chǎng)景變換到視點(diǎn)坐標(biāo)系中,;投影變換將視點(diǎn)坐標(biāo)系中的場(chǎng)景投影到二維視窗區(qū)域,;視口變換將視窗中的投影結(jié)果轉(zhuǎn)換到屏幕坐標(biāo)系中[8]。
本文討論的相關(guān)算法涉及變換序列中的投影變換和視口變換,,為了使物體在屏幕上的顯示尺寸不受所處距離遠(yuǎn)近的影響,,本文采用正投影。正投影將裁剪后的視景體投影到二維投影平面上,,映射到以像素為單位的屏幕坐標(biāo)系的過(guò)程這里簡(jiǎn)化為式(1),,因?yàn)閃indows視圖窗口所在坐標(biāo)系的默認(rèn)形式為:視圖窗口左上角為原點(diǎn),向右為X正方向,,向下為Y正方向(不考慮普通二維變換和光柵化等步驟),。
由于放大后的視景體的長(zhǎng)度和寬度都小于放大前的視景體的長(zhǎng)度和寬度,在視圖顯示窗口尺寸不變的前提下,,模型只顯示虛線中的部分,,從而達(dá)到放大的效果。
3 程序?qū)崿F(xiàn)與應(yīng)用
以VC 8.0為開(kāi)發(fā)工具,,OpenGL最小系統(tǒng)的搭建過(guò)程省略,,本文算法的主要實(shí)現(xiàn)過(guò)程及代碼如下。
3.1 定義變量
在應(yīng)用程序的頭文件里定義變量如下,,這里變量的名稱和算法中描述的一致,。
//鼠標(biāo)當(dāng)前點(diǎn)坐標(biāo)
CPoint m_MousePos,;
//鼠標(biāo)當(dāng)前點(diǎn)距離視景體左邊緣和下邊緣的距離
double Xpv1,Ypv1,;
3.2 分別為應(yīng)用程序添加WM_MOUSEMOVE和WM_MOUSEWHEEL消息
在WM_MOUSEMOVE消息的響應(yīng)函數(shù)中為定義的變量賦值,,部分代碼如下。
//獲取視圖窗口的尺寸
CRect rect,;
GetClientRect(&rect),;
//計(jì)算Xpv1和Ypv1
m_MousePos=CPoint(point.x,rect.Height()-point.y),;
double w,,h;
m_Camera.get_view_rect(w,,h),;
Xpv1=w*m_MousePos.x*1.0/rect.Width();
Ypv1=h*m_MousePos.y*1.0/rect.Height(),;
WM_MOUSEWHEEL消息響應(yīng)函數(shù)核心代碼為:
//縮放系數(shù)
double a,;
//視景體寬度和高度
double w,,h,;
//平移量
double t_x=0.0,t_y=0.0,;
if(zDelta<0)
{
//縮小系數(shù)
a=1.1,;
}
if(zDelta>0)
{
//放大系數(shù)
a=0.9;
}
//獲取視景體寬度和高度
m_Camera.get_view_rect(w,,h),;
//根據(jù)算法計(jì)算平移量
t_x=(1-a)*(0.5*w-Xpv1);
t_y=(1-a)*(0.5*h-Ypv1),;
//累計(jì)平移量
m_Camera.set_move_view(t_x,,t_y);
//縮放
m_Camera.zoom(a),;
//計(jì)算新Xpv1,,Ypv1
m_Camera.get_view_rect(w,h),;
CRect rect,;
GetClientRect(&rect);
Xpv1=w*m_MousePos.x*1.0/rect.Width(),;
Ypv1=h*m_MousePos.y*1.0/rect.Height(),;
InvalidateRect(NULL,F(xiàn)ALSE),;//刷新視圖
3.3 算法在工程計(jì)算可視化項(xiàng)目中的應(yīng)用
算法在多個(gè)可視化項(xiàng)目中得到應(yīng)用,,圖3為“風(fēng),、地震、隨機(jī)車流與橋梁交互動(dòng)力分析軟件”截圖,。一方面它能更真實(shí)地揭示出橋梁結(jié)構(gòu)在汽車車輛荷載作用下的動(dòng)態(tài)受力與變形本質(zhì),,另一方面又能描述出橋梁結(jié)構(gòu)在地震作用下的系統(tǒng)影響。因?yàn)閿?shù)據(jù)計(jì)算量大,,單純用VC++ 8.0程序計(jì)算耗時(shí)過(guò)多,,容易造成計(jì)算中斷,所以本軟件采用Fortran語(yǔ)言作為數(shù)值計(jì)算程序主體,,采用VC++ 8.0作為人機(jī)界面設(shè)計(jì)平臺(tái),,通過(guò)混合編程實(shí)現(xiàn)3種程序設(shè)計(jì)語(yǔ)言的組合、相互調(diào)用,、參數(shù)傳遞,、數(shù)據(jù)結(jié)構(gòu)與信息共享,從而形成統(tǒng)一的橋梁動(dòng)力學(xué)分析可視化軟件,。
該項(xiàng)目充分發(fā)揮Fortran語(yǔ)言在科學(xué)計(jì)算方面的優(yōu)勢(shì)及OpenGL在三維可視化渲染方面的優(yōu)勢(shì),,將工程人員多年積累的代碼資源及計(jì)算結(jié)果以圖形化展示,實(shí)現(xiàn)了橋梁結(jié)構(gòu)在風(fēng),、地震及隨機(jī)車流作用下的動(dòng)態(tài)受力與變形的可視化,。
縮放是該軟件的重要功能之一,工程可視化軟件與一般的三維模型渲染軟件的區(qū)別是:一般三維模型軟件的點(diǎn)元,、線元是基本不變的,,而工程可視化軟件中渲染的模型是變化的,重點(diǎn)是將模型在外力(車輛負(fù)荷,、風(fēng)力,、地震等)作用下的變化展示出來(lái),即點(diǎn)元,、線元的相對(duì)位置是變化的,。為了將精力集中在觀察橋梁的結(jié)構(gòu)在風(fēng)、地震及隨機(jī)車流作用下的動(dòng)態(tài)受力與變形,,在對(duì)模型進(jìn)行瀏覽時(shí)就不能不停地執(zhí)行平移放大操作,。假設(shè)圖3(a)中標(biāo)記的點(diǎn)為感興趣點(diǎn),縮放應(yīng)圍繞該目標(biāo)點(diǎn)進(jìn)行,。圖3(b)為一般算法放大后的模型效果圖,,此時(shí)的目標(biāo)點(diǎn)已經(jīng)離開(kāi)Windows視圖窗口,需要不斷平移再放大才能找到,。圖3(c)為本文算法放大后的模型效果圖,,目標(biāo)點(diǎn)依然在視圖窗口內(nèi),在對(duì)模型進(jìn)行瀏覽時(shí)不需要不停地平移即可看到模型的細(xì)節(jié),,很好地改善了用戶的操作體驗(yàn),,讓工程人員能夠?qū)W⒂跇蛄航Y(jié)構(gòu)在風(fēng),、地震及隨機(jī)車流作用下的影響。
計(jì)算機(jī)圖形學(xué)給人們提供了一種直觀的信息交流工具,,計(jì)算機(jī)圖形學(xué)已被廣泛地應(yīng)用于各個(gè)不同的領(lǐng)域,,尤其是在計(jì)算機(jī)輔助設(shè)計(jì)、計(jì)算機(jī)輔助制造和科學(xué)計(jì)算可視化等應(yīng)用領(lǐng)域,。利用本文介紹的算法,,用戶可以方便地以某一點(diǎn)為中心進(jìn)行自由縮放,及時(shí)捕捉工程計(jì)算的效果,,減少冗余操作,,改善用戶操作體驗(yàn),對(duì)開(kāi)發(fā)圖形圖像應(yīng)用軟件有一定的幫助,。
參考文獻(xiàn)
[1] 梅章明,,張秀山.基于MFC和OpenGL的噴泉模擬實(shí)現(xiàn)[J].微型機(jī)與應(yīng)用,2012,,31(14):41-43.
[2] 何煦佳,,楊榮騫,黃毅洲,,等.基于OpenGL的醫(yī)學(xué)圖像實(shí)時(shí)交互處理技術(shù)[J].計(jì)算機(jī)應(yīng)用與軟件,,2013,30(4):48-50,,64.
[3] 胡平平,,劉建明,,王晶杰.OpenGL顯示3DS模型若干問(wèn)題的研究[J].工程圖學(xué)學(xué)報(bào),,2010(4):189-193.
[4] 張舒,褚艷利.GPU高性能運(yùn)算之CUDA[M].北京:中國(guó)水利水電出版社,,2009.
[5] SHREINER D,, WOO M, NEIDER J,,等.OpenGL編程指南(第4版)[M].鄧鄭祥,,譯.北京:人民郵電出版社,2005.
[6] 崔洪斌,,秦國(guó)海,,常瑋.利用OpenGL實(shí)現(xiàn)圖形的局部放大[J].工程圖學(xué)學(xué)報(bào),,2005(6):58-61.
[7] 姜衛(wèi)東.基于OpenGL的三維函數(shù)圖象繪制[D].長(zhǎng)春:吉林大學(xué),,2007.
[8] 彭群生,金小剛,,萬(wàn)華根,,等.計(jì)算機(jī)圖形學(xué)應(yīng)用基礎(chǔ)(第1版)[M].北京:科學(xué)出版社,,2009.