OpenGL的glRotatef旋转变换函数详解

时间:2023-11-12 23:12:38

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是右手原则

最后附上代码供参考:

 #include <stdio.h>
#include <gl/glut.h> /*
功能描述:使用OpenGL简单画一个旋转的三角形
旋转变换函数glRotatef
*/ //输出模式,0-单缓存模式;非0双缓存模式
#define OUTPUT_MODE 1 //角度
int angle = ; int xyz[] = {, , }; void display(void)
{
//printf("xyz={%d, %d, %d\n}", xyz[0], xyz[1], xyz[2]); glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity();
glRotatef(angle, xyz[], xyz[], xyz[]); glBegin(GL_TRIANGLES);
{
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.5f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
}
glEnd(); angle += ;
angle %= ; if (OUTPUT_MODE == ) {
glFlush();//单缓存GLUT_SINGLE时使用
} else {
glutSwapBuffers();//因为使用的是双缓存GLUT_DOUBLE,所以这里必须要交换缓存才会显示
}
} //按键
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'x':
case 'X':
xyz[] = ;
xyz[] = xyz[] = ;
break;
case 'y':
case 'Y':
xyz[] = ;
xyz[] = xyz[] = ;
break;
case 'z':
case 'Z':
xyz[] = ;
xyz[] = xyz[] = ;
break;
case 'a':
case 'A':
xyz[] = xyz[] = xyz[] = ;
break;
case 'b':
case 'B':
xyz[] = xyz[] = xyz[] = ;
break;
default:
break;
}
printf("当前绕%c轴旋转\n", key);
glutPostRedisplay();
} void reshape(int w, int h)
{
int offset = ;
int dis = (w > h ? h : w) - offset * ; //配置显示物体屏幕的大小
glViewport(offset, offset, (GLsizei)dis, (GLsizei)dis);
printf("reshape: w=%d, h=%d, dis=%d\n", w, h, dis); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glOrtho(-1.5, 1.5, -1.5, 1.5, , );
//gluOrtho2D(-1.5, 1.5, -1.5, 1.5); glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
} int main(int argc, char *argv[])
{
printf("可通过按键xyzab控制图形旋转原点/轴\n");
glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | (OUTPUT_MODE == ? GLUT_SINGLE : GLUT_DOUBLE));
glutInitWindowPosition(, );
glutInitWindowSize(, ); glutCreateWindow("第一个 OpenGL 程序"); glutDisplayFunc(&display);
glutIdleFunc(display); //设置不断调用显示函数
glutReshapeFunc(reshape);
glutKeyboardFunc(&keyboard);
glutMainLoop();
return ;
}