机械版CG 实验3 变换

1.实验目的:

进一步掌握二维、三维变换的数学知识、变换原理、变换种类、变换方法;进一步理解采用齐次坐标进行二维、三维变换的必要性;利用OpenGL实现二维、三维图形变换。

2.实验内容:

(1)       掌握二维、三维变换的原理及数学公式;

(2)       利用OpenGL实现二维、三维图形变换,在屏幕上显示变换过程或变换结果。

3.实验原理:

  OpenGL的三个基本几何变换函数介绍如下:

1 平移变换

平移变换函数如下:

void glTranslate{fd}(TYPE x,TYPE y,TYPE z);

三个函数参数就是目标分别沿三个轴向平移的偏移量。这个函数表示用这三个偏移量生成的矩阵乘以当前矩阵。当参数是(0.0,0.0,0.0)时,表示对函数glTranslate*()的操作是单位矩阵,也就是对物体没有影响。

2 旋转变换

旋转变换函数如下:

void glRotate{fd}(TYPE angle,TYPE x,TYPE y,TYPE z);

函数中第一个参数是表示目标沿从点(x,y,z)到原点的方向逆时针旋转的角度,后三个参数是旋转的方向点坐标。这个函数表示用这四个参数生成的矩阵乘以当前矩阵。当角度参数是0.0时,表示对物体没有影响。

3 比例变换

比例变换函数如下:

void glScale{fd}(TYPE x,TYPE y,TYPE z);

三个函数参数值就是目标分别沿三个轴向缩放的比例因子。这个函数表示用这三个比例因子生成的矩阵乘以当前矩阵。这个函数能完成沿相应的轴对目标进行拉伸、压缩和反射三项功能。当参数是(1.0,1.0,1.0)时,表示对函数glScale*()操作是单位矩阵,也就是对物体没有影响。当其中某个参数为负值时,表示将对目标进行相应轴的反射变换,且这个参数不为1.0,则还要进行相应轴的缩放变换。最好不要令三个参数值都为零,这将导致目标沿三轴都缩为零。 
有关OpenGL变换详细内容还可参看:http://blog.chinaunix.net/u/26313/showart_218525.html

4.实验代码:

  

#include <GL/glut.h>

#include <stdlib.h>

GLfloat   rtri;//金字塔旋转角度

 

void init(void)

{

       glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

       glShadeModel(GL_SMOOTH);//设为smooth处理方式,注意看区别

       glEnable(GL_DEPTH_TEST);//激活深度测试

}

 

void display(void)

{

       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    //清除颜色缓存和深度缓存

       glLoadIdentity();

       glTranslatef(-1.5f,0.0f,-6.0f);//请尝试修改此函数,掌握其用法与参数含义

       glRotatef(rtri,0.0f,1.0f,0.0f);//请尝试修改此函数,掌握其用法与参数含义

       glBegin(GL_TRIANGLES);

              glColor3f(1.0f,0.0f,0.0f);

              glVertex3f( 0.0f, 1.0f, 0.0f);

              glColor3f(0.0f,1.0f,0.0f);

              glVertex3f(-1.0f,-1.0f, 1.0f);

              glColor3f(0.0f,0.0f,1.0f);

              glVertex3f( 1.0f,-1.0f, 1.0f);

 

              glColor3f(1.0f,0.0f,0.0f);

              glVertex3f( 0.0f, 1.0f, 0.0f);

              glColor3f(0.0f,0.0f,1.0f);

              glVertex3f( 1.0f,-1.0f, 1.0f);

              glColor3f(0.0f,1.0f,0.0f);

              glVertex3f( 1.0f,-1.0f, -1.0f);

 

              glColor3f(1.0f,0.0f,0.0f);

              glVertex3f( 0.0f, 1.0f, 0.0f);

              glColor3f(0.0f,1.0f,0.0f);

              glVertex3f( 1.0f,-1.0f, -1.0f);

              glColor3f(0.0f,0.0f,1.0f);

              glVertex3f(-1.0f,-1.0f, -1.0f);

 

              glColor3f(1.0f,0.0f,0.0f);

              glVertex3f( 0.0f, 1.0f, 0.0f);

              glColor3f(0.0f,0.0f,1.0f);

              glVertex3f(-1.0f,-1.0f,-1.0f);

              glColor3f(0.0f,1.0f,0.0f);

              glVertex3f(-1.0f,-1.0f, 1.0f);

       glEnd();

 

      

       rtri+=0.1f;//加一个角度

       glutSwapBuffers();//交换双缓存

}

 

void reshape (int width, int height)

{

       glViewport(0, 0, width, height);

       glMatrixMode(GL_PROJECTION);

       glLoadIdentity();

       gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f);

       glMatrixMode(GL_MODELVIEW);

       glLoadIdentity();

}

 

void keyboard(unsigned char key, int x, int y)

{//请参考"变换示例参考"一文,考虑添加键盘命令,交互式来控制金字塔的旋转

       switch (key)

       {

              case ‘x’:

                     exit(0);

                     break;

              default:

                     break;

   }

}

 

int main(int argc, char** argv)

{

       glutInit(&argc, argv);

       glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);//使用双缓存模式和深度缓存

       glutInitWindowSize(640, 480);

       glutInitWindowPosition(100, 100);

       glutCreateWindow("Transform2");

       init();

       glutDisplayFunc(display);

       glutReshapeFunc(reshape);

       glutKeyboardFunc(keyboard);

       glutIdleFunc(display);//设置空闲时调用的函数

       glutMainLoop();

       return 0;

}

 

 

代码注释:

 这个程序需要注意的地方有几点。

使用了双缓存模式,程序在空闲时一直不停的调用display函数,这个函数绘制完图像后,改变旋转的角度,然后交换双缓存,这样,每画完一帧就交换,形成了动画。

另外,使用了深度缓存,激活了深度测试,这样,被遮挡的面就不会显示,大家可以把激活深度缓存的一行去掉看看效果。大家还可以改变变换的方式,达到不同的效果。

5.思考题 

参考"CG实验指导四参考实例"一文考虑为本程序加上键盘交互控制功能,使得通过键盘可以控制对象的运动方式,如不同的旋转,或绕X轴或绕Z轴等.

原文地址:https://www.cnblogs.com/opengl/p/937879.html