在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Android/ 3D 坐標(biāo)變換
3D 繪圖基本概念
概述
真正的 3D 圖形
添加顏色
3D 坐標(biāo)變換
構(gòu)造
材質(zhì)渲染

3D 坐標(biāo)變換

本篇介紹 3D 坐標(biāo)系下的坐標(biāo)變換 transformations。

Coordinate System坐標(biāo)系

OpenGL 使用了右手坐標(biāo)系統(tǒng),右手坐標(biāo)系判斷方法:在空間直角坐標(biāo)系中,讓右手拇指指向x軸的正方向,食指指向y軸的正方向,如果中指能指向z軸的正方向,則稱這個(gè)坐標(biāo)系為右手直角坐標(biāo)系。

http://wiki.jikexueyuan.com/project/opengl-es-basics/images/15.png" alt="" />

Translate 平移變換

方法 public abstract void glTranslatef (float x, float y, float z) 用于坐標(biāo)平移變換。

在上個(gè)例子中我們把需要顯示的正方形后移了4個(gè)單位,就是使用的坐標(biāo)的平移變換,可以進(jìn)行多次平移變換,其結(jié)果為多個(gè)平移矩陣的累計(jì)結(jié)果,矩陣的順序不重要,可以互換。

http://wiki.jikexueyuan.com/project/opengl-es-basics/images/16.png" alt="" />

Rotate 旋轉(zhuǎn)

方法 public abstract void glRotatef(float angle, float x, float y, float z) 用來(lái)實(shí)現(xiàn)選擇坐標(biāo)變換,單位為角度。(x,y,z)定義旋轉(zhuǎn)的參照矢量方向。多次旋轉(zhuǎn)的順序非常重要。

http://wiki.jikexueyuan.com/project/opengl-es-basics/images/17.png" alt="" />

比如你選擇一個(gè)骰子,首先按下列順序選擇3次:

gl.glRotatef(90f, 1.0f, 0.0f, 0.0f);
gl.glRotatef(90f, 0.0f, 1.0f, 0.0f);
gl.glRotatef(90f, 0.0f, 0.0f, 1.0f);  

http://wiki.jikexueyuan.com/project/opengl-es-basics/images/18.png" alt="" />

然后打算逆向旋轉(zhuǎn)回原先的初始狀態(tài),需要有如下旋轉(zhuǎn):

gl.glRotatef(90f, -1.0f, 0.0f, 0.0f);
gl.glRotatef(90f, 0.0f, -1.0f, 0.0f);
gl.glRotatef(90f, 0.0f, 0.0f, -1.0f);  

http://wiki.jikexueyuan.com/project/opengl-es-basics/images/19.png" alt="" />

或者如下旋轉(zhuǎn):

gl.glRotatef(90f, 0.0f, 0.0f, -1.0f);
gl.glRotatef(90f, 0.0f, -1.0f, 0.0f);
gl.glRotatef(90f, -1.0f, 0.0f, 0.0f);  

旋轉(zhuǎn)變換 glRotatef(angle, -x, -y, -z)glRotatef(-angle, x, y, z) 是等價(jià)的,但選擇變換的順序直接影響最終坐標(biāo)變換的結(jié)果。 角度為正時(shí)表示逆時(shí)針?lè)较颉?/p>

Translate & Rotate (平移和旋轉(zhuǎn)組合變換)

在對(duì) Mesh(網(wǎng)格,構(gòu)成三維形體的基本單位)同時(shí)進(jìn)行平移和選擇變換時(shí),坐標(biāo)變換的順序也直接影響最終的結(jié)果。

比如:先平移后旋轉(zhuǎn),旋轉(zhuǎn)的中心為平移后的坐標(biāo)。

http://wiki.jikexueyuan.com/project/opengl-es-basics/images/20.png" alt="" />

先選擇后平移: 平移在則相對(duì)于旋轉(zhuǎn)后的坐標(biāo)系:

http://wiki.jikexueyuan.com/project/opengl-es-basics/images/21.png" alt="" />

一個(gè)基本原則是,坐標(biāo)變換都是相對(duì)于變換的 Mesh 本身的坐標(biāo)系而進(jìn)行的。

Scale(縮放)

方法 public abstract void glScalef (float x, float y, float z)用于縮放變換。

下圖為使用 gl.glScalef(2f, 2f, 2f) 變換后的基本,相當(dāng)于把每個(gè)坐標(biāo)值都乘以2.

http://wiki.jikexueyuan.com/project/opengl-es-basics/images/22.png" alt="" />

Translate & Scale(平移和縮放組合變換)

同樣當(dāng)需要平移和縮放時(shí),變換的順序也會(huì)影響最終結(jié)果。

比如先平移后縮放:

gl.glTranslatef(2, 0, 0);
gl.glScalef(0.5f, 0.5f, 0.5f);  

http://wiki.jikexueyuan.com/project/opengl-es-basics/images/23.png" alt="" />

如果調(diào)換一下順序:

gl.glScalef(0.5f, 0.5f, 0.5f);
gl.glTranslatef(2, 0, 0);  

結(jié)果就有所不同:

http://wiki.jikexueyuan.com/project/opengl-es-basics/images/24.png" alt="" />

矩陣操作,單位矩陣

在進(jìn)行平移,旋轉(zhuǎn),縮放變換時(shí),所有的變換都是針對(duì)當(dāng)前的矩陣(與當(dāng)前矩陣相乘),如果需要將當(dāng)前矩陣回復(fù)最初的無(wú)變換的矩陣,可以使用單位矩陣(無(wú)平移,縮放,旋轉(zhuǎn))。

public abstract void glLoadIdentity()。

在棧中保存當(dāng)前矩陣和從棧中恢復(fù)所存矩陣,可以使用

public abstract void glPushMatrix()

public abstract void glPopMatrix()。

在進(jìn)行坐標(biāo)變換的一個(gè)好習(xí)慣是在變換前使用 glPushMatrix 保存當(dāng)前矩陣,完成坐標(biāo)變換操作后,再調(diào)用 glPopMatrix 恢復(fù)原先的矩陣設(shè)置。

最后利用上面介紹的坐標(biāo)變換知識(shí),來(lái)繪制 3 個(gè)正方形 A,B,C。進(jìn)行縮放變換,使的 B 比 A 小 50%,C 比 B 小 50%。 然后以屏幕中心逆時(shí)針旋轉(zhuǎn) A,B 以 A 為中心順時(shí)針旋轉(zhuǎn),C 以 B 為中心順時(shí)針旋轉(zhuǎn)同時(shí)以自己中心高速逆時(shí)針旋轉(zhuǎn)。

修改 onDrawFrame 代碼如下:

public void onDrawFrame(GL10 gl) {
 // Clears the screen and depth buffer.
 gl.glClear(GL10.GL_COLOR_BUFFER_BIT
 | GL10.GL_DEPTH_BUFFER_BIT);
 // Replace the current matrix with the identity matrix
 gl.glLoadIdentity();
 // Translates 10 units into the screen.
 gl.glTranslatef(0, 0, -10);
 // SQUARE A
 // Save the current matrix.
 gl.glPushMatrix();
 // Rotate square A counter-clockwise.
 gl.glRotatef(angle, 0, 0, 1);
 // Draw square A.
 square.draw(gl);
 // Restore the last matrix.
 gl.glPopMatrix();
 // SQUARE B
 // Save the current matrix
 gl.glPushMatrix();
 // Rotate square B before moving it,
 //making it rotate around A.
 gl.glRotatef(-angle, 0, 0, 1);
 // Move square B.
 gl.glTranslatef(2, 0, 0);
 // Scale it to 50% of square A
 gl.glScalef(.5f, .5f, .5f);
 // Draw square B.
 square.draw(gl);
 // SQUARE C
 // Save the current matrix
 gl.glPushMatrix();
 // Make the rotation around B
 gl.glRotatef(-angle, 0, 0, 1);
 gl.glTranslatef(2, 0, 0);
 // Scale it to 50% of square B
 gl.glScalef(.5f, .5f, .5f);
 // Rotate around it's own center.
 gl.glRotatef(angle*10, 0, 0, 1);
 // Draw square C.
 square.draw(gl);
 // Restore to the matrix as it was before C.
 gl.glPopMatrix();
 // Restore to the matrix as it was before B.
 gl.glPopMatrix();
 // Increse the angle.
 angle++;
 }  

http://wiki.jikexueyuan.com/project/opengl-es-basics/images/25.png" alt="" />

本例代碼下載

上一篇:真正的 3D 圖形下一篇:添加顏色