鍍金池/ 教程/ Android/ 3D 坐標變換
                                          3D 繪圖基本概念
                                          概述
                                          真正的 3D 圖形
                                          添加顏色
                                          3D 坐標變換
                                          構造
                                          材質渲染

                                          3D 坐標變換

                                          本篇介紹 3D 坐標系下的坐標變換 transformations。

                                          Coordinate System坐標系

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

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

                                          Translate 平移變換

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

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

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

                                          Rotate 旋轉

                                          方法 public abstract void glRotatef(float angle, float x, float y, float z) 用來實現選擇坐標變換,單位為角度。(x,y,z)定義旋轉的參照矢量方向。多次旋轉的順序非常重要。

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

                                          比如你選擇一個骰子,首先按下列順序選擇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="" />

                                          然后打算逆向旋轉回原先的初始狀態,需要有如下旋轉:

                                          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="" />

                                          或者如下旋轉:

                                          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);  

                                          旋轉變換 glRotatef(angle, -x, -y, -z)glRotatef(-angle, x, y, z) 是等價的,但選擇變換的順序直接影響最終坐標變換的結果。 角度為正時表示逆時針方向。

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

                                          在對 Mesh(網格,構成三維形體的基本單位)同時進行平移和選擇變換時,坐標變換的順序也直接影響最終的結果。

                                          比如:先平移后旋轉,旋轉的中心為平移后的坐標。

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

                                          先選擇后平移: 平移在則相對于旋轉后的坐標系:

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

                                          一個基本原則是,坐標變換都是相對于變換的 Mesh 本身的坐標系而進行的。

                                          Scale(縮放)

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

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

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

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

                                          同樣當需要平移和縮放時,變換的順序也會影響最終結果。

                                          比如先平移后縮放:

                                          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="" />

                                          如果調換一下順序:

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

                                          結果就有所不同:

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

                                          矩陣操作,單位矩陣

                                          在進行平移,旋轉,縮放變換時,所有的變換都是針對當前的矩陣(與當前矩陣相乘),如果需要將當前矩陣回復最初的無變換的矩陣,可以使用單位矩陣(無平移,縮放,旋轉)。

                                          public abstract void glLoadIdentity()。

                                          在棧中保存當前矩陣和從棧中恢復所存矩陣,可以使用

                                          public abstract void glPushMatrix()

                                          public abstract void glPopMatrix()。

                                          在進行坐標變換的一個好習慣是在變換前使用 glPushMatrix 保存當前矩陣,完成坐標變換操作后,再調用 glPopMatrix 恢復原先的矩陣設置。

                                          最后利用上面介紹的坐標變換知識,來繪制 3 個正方形 A,B,C。進行縮放變換,使的 B 比 A 小 50%,C 比 B 小 50%。 然后以屏幕中心逆時針旋轉 A,B 以 A 為中心順時針旋轉,C 以 B 為中心順時針旋轉同時以自己中心高速逆時針旋轉。

                                          修改 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 圖形下一篇:添加顏色
                                          人妻精品动漫h无码中字