OpenGL的glRotatef旋轉變換函數詳解


OpenGL的glRotatef旋轉變換函數詳解

先看一下函數定義:
void glRotatef(GLfloat angle,
         GLfloat x,
           GLfloat y,
           GLfloat z)

angle:為旋轉的角度,單位為度。
x,y,z:為對應xyz軸的布爾值變量

重點是x,y,z表達的是什么意思呢?應該如何取值?
如果說x,y,z表達的是一個坐標(x,y,z),那么這個函數就說明了當前幾何圖形圍着這個坐標點旋轉。

但往哪個方向旋轉呢?所以很明顯,x,y,z表達的意思並不是坐標點,而是要圍繞哪個坐標軸旋轉
即其實這里的x,y,z值相當於一個布爾值,0.0表示假,而非零參數則表示真。
所以如果你想讓當前的幾何圖形圍繞着z軸旋轉,那么x和y都設為0,而z設為非零值即可。
如果這里的x,y,z的值都設置為0.0,那么將圍繞着x軸旋轉。

還有一點需要注意,如果設置的旋轉值(x,y,z的值)為正數,那么旋轉的方向是逆時針的,如果旋轉值是負數,那么旋轉的方向是順時針的

假設:glRotatef(45,1,0,0)

物體如何旋轉?
想象:從坐標(0,0,0)即原點,引出一條線到(1,0,0),用右手握住這條線.
這時,你會問,如何握?
右手大拇指指向(0,0,0)至(1,0,0)的方向才握。
另外四個手指的彎曲指向即是物體旋轉方向。

為什么是右手握住,而不是左手呢?
因為OpenGL是右手原則

 

最后附上代碼供參考:

  1 #include <stdio.h>
  2 #include <gl/glut.h>
  3 
  4 /*
  5  功能描述:使用OpenGL簡單畫一個旋轉的三角形
  6  旋轉變換函數glRotatef
  7  */
  8 
  9 //輸出模式,0-單緩存模式;非0雙緩存模式
 10 #define OUTPUT_MODE 1
 11 
 12 //角度
 13 int angle = 0;
 14 
 15 int xyz[3] = {0, 0, 0};
 16 
 17 void display(void)
 18 {
 19     //printf("xyz={%d,  %d,  %d\n}", xyz[0], xyz[1], xyz[2]);
 20 
 21     glClear(GL_COLOR_BUFFER_BIT);
 22 
 23 
 24     glLoadIdentity();
 25     glRotatef(angle, xyz[0], xyz[1], xyz[2]);
 26 
 27     glBegin(GL_TRIANGLES);
 28     {
 29         glVertex3f(0.0f, 0.0f, 0.0f);
 30         glVertex3f(0.5f, 0.0f, 0.0f);
 31         glVertex3f(0.0f, 0.5f, 0.0f);
 32     }
 33     glEnd();
 34 
 35     angle += 1;
 36     angle %= 360;
 37 
 38     if (OUTPUT_MODE == 0) {
 39         glFlush();//單緩存GLUT_SINGLE時使用
 40     } else {
 41         glutSwapBuffers();//因為使用的是雙緩存GLUT_DOUBLE,所以這里必須要交換緩存才會顯示
 42     }
 43 }
 44 
 45 //按鍵
 46 void keyboard(unsigned char key, int x, int y)
 47 {
 48     switch (key)
 49     {
 50     case 'x':
 51     case 'X':
 52         xyz[0] = 1;
 53         xyz[1] = xyz[2] = 0;
 54         break;
 55     case 'y':
 56     case 'Y':
 57         xyz[1] = 1;
 58         xyz[0] = xyz[2] = 0;
 59         break;
 60     case 'z':
 61     case 'Z':
 62         xyz[2] = 1;
 63         xyz[0] = xyz[1] = 0;
 64         break;
 65     case 'a':
 66     case 'A':
 67         xyz[0] = xyz[1] = xyz[2] = 0;
 68         break;
 69     case 'b':
 70     case 'B':
 71         xyz[0] = xyz[1] = xyz[2] = 1;
 72         break;
 73     default:
 74         break;
 75     }
 76     printf("當前繞%c軸旋轉\n", key);
 77     glutPostRedisplay();
 78 }
 79 
 80 void reshape(int w, int h)
 81 {
 82     int offset = 50;
 83     int dis = (w > h ? h : w) - offset * 2;
 84     
 85     //配置顯示物體屏幕的大小
 86     glViewport(offset, offset, (GLsizei)dis, (GLsizei)dis);
 87     printf("reshape: w=%d, h=%d, dis=%d\n", w, h, dis);
 88 
 89     glMatrixMode(GL_PROJECTION);
 90     glLoadIdentity();
 91 
 92     glOrtho(-1.5, 1.5, -1.5, 1.5, 0, 10);
 93     //gluOrtho2D(-1.5, 1.5, -1.5, 1.5);
 94 
 95     glMatrixMode(GL_MODELVIEW);
 96     glLoadIdentity();
 97 }
 98 
 99 int main(int argc, char *argv[])
100 {
101     printf("可通過按鍵xyzab控制圖形旋轉原點/軸\n");
102     glutInit(&argc, argv);
103     
104     glutInitDisplayMode(GLUT_RGB | (OUTPUT_MODE == 0 ? GLUT_SINGLE : GLUT_DOUBLE));
105     glutInitWindowPosition(100, 100);
106     glutInitWindowSize(400, 400);
107 
108     glutCreateWindow("第一個 OpenGL 程序");
109 
110     glutDisplayFunc(&display);
111     glutIdleFunc(display);  //設置不斷調用顯示函數
112     glutReshapeFunc(reshape);
113     glutKeyboardFunc(&keyboard);
114     glutMainLoop();
115     return 0;
116 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM