999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于OpenGL的射線拾取的探討

2011-12-31 00:00:00劉薇
科技創(chuàng)新導(dǎo)報(bào) 2011年11期

摘 要:研究了用射線來拾取對(duì)象的原理,分析了如何利用模型矩陣從二維屏幕坐標(biāo)選取三維空間圖元,提出了兩種射線拾取的實(shí)現(xiàn)方法以及可能存在的問題。

關(guān)鍵詞:OpenGL 射線拾取 模型矩陣

中圖分類號(hào):TP31文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1674-098X(2011)04(b)-0088-02

1 引言

OpenGL是一個(gè)性能優(yōu)越的圖形應(yīng)用程序設(shè)計(jì)界面,廣泛地應(yīng)用于科學(xué)計(jì)算可視化、視景仿真、虛擬現(xiàn)實(shí)等領(lǐng)域。

拾取是計(jì)算機(jī)圖形處理系統(tǒng)一個(gè)重要功能。拾取是圖形繪制、操作者通過輸入設(shè)備操縱屏幕上的物體、獲取物體的空間坐標(biāo)或圖形數(shù)值的實(shí)現(xiàn)基礎(chǔ)。OpenGL中物體的拾取是人機(jī)實(shí)時(shí)交互技術(shù)的一部分。它是由操作者通過輸入設(shè)備輸入信息,然后選取屏幕上顯示的物體。射線拾取法是根據(jù)二維屏幕坐標(biāo)來選取三維空間中的圖元,通過獲取鼠標(biāo)在二維屏幕上的點(diǎn),經(jīng)屏幕坐標(biāo)轉(zhuǎn)換得到投影點(diǎn),以視點(diǎn)為起點(diǎn),經(jīng)投影點(diǎn)構(gòu)造一條垂直指向屏幕的射線。射線拾取涉及到空間變換。在Opengl里面,空間變換是通過矩陣運(yùn)算完成的。

2 射線拾取技術(shù)原理

所謂空間變換就是,假設(shè)模型有三個(gè)頂點(diǎn)A、B、C,這三個(gè)頂點(diǎn)在模型坐標(biāo)系中就是固定的。但是如果要在兩個(gè)位置繪制兩個(gè)相同的模型,那么就要將模型頂點(diǎn)變換到世界空間中,A、B、C三點(diǎn)這時(shí)候可能對(duì)于兩個(gè)物體就產(chǎn)生了A1、B1、C1和A2、B2、C2兩組不同的坐標(biāo),這兩個(gè)新的坐標(biāo)就是在世界空間中的。

OpenGL里面調(diào)用glDrawArray或者類似函數(shù)繪制多邊形之前,都會(huì)有許多矩陣變換函數(shù),也就是說,多邊形一定是通過這些矩陣把位置擺好以后,才送到設(shè)備繪制出來的,在調(diào)用任何矩陣函數(shù)之前,原始頂點(diǎn)坐標(biāo)就是模型空間中的坐標(biāo),當(dāng)該坐標(biāo)乘以了模型矩陣之后就將它們變換到了世界空間中,乘以視圖矩陣后就變換到視圖空間中,再乘以投影矩陣就變換到投影空間中。

使用模型矩陣可以將模型坐標(biāo)系中的頂點(diǎn)變換到世界坐標(biāo)系中,而把射線從世界坐標(biāo)系變換到模型坐標(biāo)系中,則需要先求出模型矩陣的逆矩陣,然后用這個(gè)逆矩陣去變換射線,變換后的結(jié)果就是射線在模型坐標(biāo)系中的表示。從而可以用來與模型坐標(biāo)系中的包圍球進(jìn)行相交檢測,更深入一步可以與三角形進(jìn)行相交檢測。

3 代碼實(shí)現(xiàn)

3.1 獲取模型矩陣

在研究中總結(jié)出兩種方法獲取模型矩陣。第一種方法是,自己計(jì)算變換矩陣,而不是使用像OpenGL中的glTranlate/glRotate這樣的函數(shù)。代碼如下:

/***world coordinate to scene coordinate;

*@param[in] objX world coord: X

*@param[in] objY world coord: Y

*@param[in] objZ world coord: Z

*return RETURN the scene coord.

**/

Tuple3f SceneOBJ::WorldToScene(float objX,float objY,float objZ)

{

GLint realy;

GLdouble win_x,win_y,win_z;

int viewport[4];

double mvmatrix[16],projmatrix[16];

//::wglMakeCurrent(m_hDC,m_hRC);

glGetIntegerv(GL_VIEWPORT,viewport);

for(int i=0;i<16;i++)

mvmatrix[i] = Trans_Matrix.m[i];

glGetDoublev(GL_PROJECTION_MATRIX,projmatrix);

gluProject((GLdouble)objX,(GLdouble)objY,(GLdouble)objZ,mvmatrix,projmatrix,viewport,win_x,win_y,win_z);

realy = viewport[3]-(GLint)win_y -1;// 左上角為坐標(biāo)原點(diǎn)

Tuple3f temp(win_x,realy,win_z);

//::wglMakeCurrent(NULL,NULL);

return temp;

}

//

第二種方法是,先創(chuàng)建一個(gè)世界坐標(biāo)系矩陣float gModelMatrix[],然后在

glPushMatrix和glPopMatri之間使用渲染回調(diào)函數(shù)中的glGetFloatv(GL_

MODELVIEW_MATRIX, gModelMatrix)

void Render()

{

glPushMatrix()

glTrinslatef(...)

glRotatef(....)

glGetFloatv(GL_MODELVIEW_MATRIX, gModelMatrix);\"

draw_obj();

glPopMatrix();

}

3.2 變換射線的代碼

glGetDoublev(GL_MODELVIEW_MATRIX,ModelView);//獲取視圖矩陣

glGetDoublev(GL_PROJECTION_MATRIX,Projection);//獲取投影矩陣

glGetIntegerv(GL_VIEWPORT,ViewPort);//獲取視口大小

gluUnProject((double)Mouse_x, //獲取近點(diǎn)坐標(biāo)

(double)ViewPort[3]-Mouse_y,

0.0f,

ModelView,

Projection,

ViewPort,

Near_p.x,

Near_p.y,

Near_p.z

);

3.3 利用拾取射線和包圍球的的交叉測試來完成拾取

一個(gè)模型往往有數(shù)百個(gè)面,將一組物體完全包容成封閉空間,用簡單的包圍體封裝復(fù)雜模型,可以極大提高幾何運(yùn)算的效率。常用的包圍體有:包圍球、包圍盒。

// 射線與包圍球的相交檢測Dist:傳回交點(diǎn)到起點(diǎn)的距離

BOOL CBoundBox::RayIntersectSphere(Point3F StartLine, Point3F EndLine,float Dist,ModelItem *pItem)

{

//getPoint3FtoVector3 Point3F結(jié)構(gòu)轉(zhuǎn)CVector3

CVector3 Direction=getPoint3FtoVector3(EndLine)-getPoint3FtoVector3(StartLine);

Direction.Normalize();//歸一化向量

CVector3 Start=getPoint3FtoVector3(StartLine);

//Start=Start-getPoint3FtoVector3(pItem->Point);

CVector3 Center=getPoint3FtoVector3(pItem->Point);

CVector3 Rayorig = Start - Center;

Rayorig.Normalize();

float Radius = pItem->Point.h;

//先判斷起點(diǎn)是不是在球內(nèi)

if(Rayorig.GetLength()*Rayorig.GetLength()<=Radius*Radius)

{

Dist=0;

return 1; //射線的啟點(diǎn)一直在這里

}

float a = Direction.Dot(Direction);Dot//點(diǎn)乘

float b = 2*Rayorig.Dot(Direction);

float c = Rayorig.Dot(Rayorig)-Radius*Radius;

float d = (b*b)-(4*a*c);

if(d<0)

{

Dist=0;

return 1;

}

else

{

float t=(-b-sqrt(d))/(2*a);

if(t<0)

t=(-b+sqrt(d))/(2*a);

Dist=t;

return true;

}

}

//射線的啟點(diǎn)一直在球內(nèi)

pItem 這個(gè)結(jié)構(gòu)里是模型的中點(diǎn)坐標(biāo),及模型的長,寬,高,中點(diǎn)坐標(biāo),就是坐標(biāo)平移的量。

最后需要特別注意的是,射線和模型兩者必須在同一個(gè)空間中,最后獲取到的交點(diǎn)也是在這個(gè)空間中的坐標(biāo)

4 結(jié)語

本文研究了射線拾取的兩種方法,并且分析了射線拾取在代碼實(shí)現(xiàn)中可能遇到的問題,提出了解決方案。

參考文獻(xiàn)

[1]孫家廣,楊長貴著.計(jì)算機(jī)圖形學(xué)[M].北京:清華大學(xué)出版社,1995:369,373.

[2]向世明.OpenGL編程與實(shí)例.電子工業(yè)出版社,2000,2.

[3]http://www.opengl.org/.

主站蜘蛛池模板: 伊人久久综在合线亚洲91| 欧美色香蕉| www.91在线播放| 免费在线成人网| 一级在线毛片| 青青操视频免费观看| 国产成人无码久久久久毛片| 这里只有精品国产| 国产精品福利导航| 成人福利在线免费观看| 中国黄色一级视频| 激情成人综合网| 国产麻豆精品在线观看| 婷婷激情五月网| 免费AV在线播放观看18禁强制| 女人18毛片水真多国产| 日本尹人综合香蕉在线观看| 免费 国产 无码久久久| 日韩少妇激情一区二区| 精品福利国产| Jizz国产色系免费| 国产精品亚洲欧美日韩久久| 亚洲日本一本dvd高清| 99re视频在线| 国产全黄a一级毛片| 国产精品久线在线观看| 亚洲精品另类| 制服丝袜一区| 国产成人AV男人的天堂| 91福利国产成人精品导航| 91精品国产自产在线老师啪l| 青青操国产| 日本免费一级视频| 久久永久精品免费视频| 国产午夜精品鲁丝片| 日韩在线网址| 色偷偷综合网| 国产自视频| 亚洲国产日韩在线观看| 人人澡人人爽欧美一区| 免费可以看的无遮挡av无码| 国产综合色在线视频播放线视| 午夜激情婷婷| 黄色在线网| 日韩精品一区二区三区视频免费看| www.youjizz.com久久| 粉嫩国产白浆在线观看| 国产中文在线亚洲精品官网| 国产情精品嫩草影院88av| 日韩免费成人| 91无码视频在线观看| 精品91在线| 成人小视频网| 亚洲综合久久一本伊一区| 99久久这里只精品麻豆| 2020最新国产精品视频| 日本三级精品| 毛片在线播放a| 久久男人资源站| 欧美午夜在线视频| 精品人妻AV区| 新SSS无码手机在线观看| 亚洲欧美另类视频| 国产在线欧美| 国产福利观看| 就去吻亚洲精品国产欧美| 亚洲高清无在码在线无弹窗| 亚洲VA中文字幕| 91精品国产一区自在线拍| 国产成人综合亚洲网址| 久久精品丝袜| 亚洲不卡av中文在线| 国产成人禁片在线观看| 国产在线观看第二页| 久久国产精品波多野结衣| 亚洲精品无码日韩国产不卡| 91九色最新地址| 东京热av无码电影一区二区| 婷婷开心中文字幕| 少妇人妻无码首页| 国产丝袜精品| 噜噜噜久久|