实验六 2D图形变换

ZZU的学弟学妹们不要抄作业哦~(`Д´)

一、实验目的

1.了解和掌握2D图形变换:学会使用OpenGL平移、旋转和比例缩放函数,掌握基本图形变换和复合图形变换实现的方法。

2.综合运用2D图形变换函数、人机交互函数,设计2D交互图形程序。

 

二、实验内容

要求使用OpenGL几何变换函数改写代码。

1)使用glTranslatef()函数,实现2D图形平移,可以改写实验二的矩形交互移动程序,如图6-1。

实验六 2D图形变换_第1张图片 实验六 2D图形变换_第2张图片

 

                     a)平移前                                      b)平移后

                                            图6-1 平移变换

 

 

2)使用glRotatef()函数,实现2D图形绕平面固定点旋转,可以改写实验三的六边形旋转程序,如图6-2。

实验六 2D图形变换_第3张图片实验六 2D图形变换_第4张图片

                   a)旋转前                                         b)旋转后

                                          图6-2 旋转变化

 

 

3)使用glScalef()函数,实现绕固定点缩放2D图形,在前面程序的基础上设计修改,如图6-3。

实验六 2D图形变换_第5张图片实验六 2D图形变换_第6张图片

                   a)缩放前                                           b)缩放后

                                              图6-3 比例变换

 

4)修改代码,使得一面带杆小三角红旗沿着杆底不断旋转,如图6-4

实验六 2D图形变换_第7张图片实验六 2D图形变换_第8张图片

                                 图6-4 旋转的小红旗

 

 

5)正六边形边旋转边放大,放大到接近整个显示屏后再不停缩小,如此往复。

实验六 2D图形变换_第9张图片实验六 2D图形变换_第10张图片        实验六 2D图形变换_第11张图片实验六 2D图形变换_第12张图片

 

三、参考函数

1.glTranslatef(x,y,z);//x、y、z分别代表x、y、z方向的平移量,对于2D图形,z=0

2.glRotatef(Q,x,y,z);//Q为逆时针方向旋转的角度度数(0~360),(x,y,z)为旋转轴的方向矢量,(x,y,z)=(0,0,1)时代表沿z轴方向旋转;(x,y,z)=(1,0,0)时代表沿x轴方向旋转;(x,y,z)=(0,1,0)时代表沿y轴方向旋转。

3.glScalef(x,y,z);//x、y、z分别表示x、y、z方向的比例因子。对于2D图形,z=0。比例因子取-1时,产生对称变换。

 

四、代码示例

1.某图形沿水平方向和垂直方向分别平移Tx、Ty段距离。

 

清屏

glMatrixMode(GL_MODELVIEW);//设置矩阵模式为模型变换模式,表示在世界坐标系下

glLoadIdentity();//将当前矩阵设置为单位矩阵

glTranslatef(Tx,Ty,0)

DrawSomeShape();

刷新

 

2.某图形绕任意点(cx,cy)旋转ALPHA角度。

 

清屏

glMatrixMode(GL_MODELVIEW);//设置矩阵模式为模型变换模式,表示在世界坐标系下

glLoadIdentity();//将当前矩阵设置为单位矩阵

glTranslatef(cx,cy,0)//平移回去

glRotatef(ALPHA,0,0,1);//绕原点旋转ALPHA角度

glTranslatef(-cx,-cy,0)//平移回原点

DrawSomeShape();

刷新

 

3.某图形绕任意点(cx,cy)缩放Sx、Sy比例因子。

 

清屏

glMatrixMode(GL_MODELVIEW);//设置矩阵模式为模型变换模式,表示在世界坐标系下

glLoadIdentity();//将当前矩阵设置为单位矩阵

glTranslatef(cx,cy,0)//平移回去

glScalef(Sx,Sy,1);//绕原点水平缩放系数Sx,垂直缩放系数Sy

glTranslatef(-cx,-cy,0)//平移回原点

DrawSomeShape();

刷新

 

五、思考题

1.绕某个固定点旋转时,代码的顺序改写为:

glTranslatef(-cx,-cy,0)//平移回原点

glRotatef(ALPHA,0,0,1);//绕原点旋转ALPHA角度

glTranslatef(cx,cy,0)//平移回去

图形将变成怎样?

答:图形形状不变,但是位置会改变。因为因为glTranslatef的变换是以当前位置来变换的,也就是说用的是相对坐标而不是绝对坐标。

 

2.绕某个固定点进行比例缩放时,代码的顺序改写为:

glTranslatef(-cx,-cy,0)//平移回原点

glScalef(Sx,Sy,1);//绕原点水平缩放系数Sx,垂直缩放系数Sy

glTranslatef(cx,cy,0)//平移回去

图形将变成怎样?为什么?

答:会缩放,但是位置会改变。因为缩放是相对于原点进行的,而不是自身的中心。当平移后再缩放,再平移回去,会改变坐标。

 

六、完整代码

#include
#include
#include
#include"math.h"
#define PI 3.1415926

int n = 6,flag=0;
float R = 0.5,theta=0,sx=1,sy=1;

void myidle()
{
	theta += 1.0;
	Sleep(5);
	if (theta >= 360) theta -= 360;
	/*if (sx >= 2.83) flag = 1;
	if (sx <= 0.1) flag = 0;
	if (flag == 0)
	{
		sx *= 1.01, sy *= 1.01;
	}
	if(flag==1)
	{
		sx *= 0.99, sy *=0.99;
	}*/
	glutPostRedisplay();
}

void display(void)
{
	glClearColor(1, 1, 1, 1);//设置清屏颜色
	glClear(GL_COLOR_BUFFER_BIT);//刷新颜色缓存区
	glColor3f(0, 0, 0); //设置黑色绘图颜色



	glMatrixMode(GL_MODELVIEW);//设置矩阵模式为模型变换模式,表示在世界坐标系下
	glLoadIdentity();//将当前矩阵设置为单位矩阵
	glTranslatef(-0.5, -0.5, 0);//平移回原点
	glScalef(0.5, 0.5, 1);//绕原点水平缩放系数Sx,垂直缩放系数Sy
	//glTranslatef(0.5, 0.5, 0);//平移回去
	//glTranslatef(0.5, 0.5, 0);//平移
	//glRotatef(45, 0, 0, 1);//绕z轴旋转45°
	//glScalef(0.5, 0.5, 0);//缩小
	//glRotatef(theta, 0, 0, 1);//绕z轴不停旋转
	//glScalef(sx, sy, 0);//放大
	glRectf(-0.5, -0.5,0.5,0.5);//矩形
	/*glBegin(GL_POLYGON);  //六边形
	for (int i = 0; i < n; i++)
		glVertex2f(R*cos(i * 2 * PI / n), R*sin(i * 2 * PI / n));
	glEnd();

	*/
	/*
	glColor3f(1, 0, 0); //画小红旗
	glBegin(GL_LINES);
	glVertex2f(0, 0);
	glVertex2f(0, 0.7);
	glEnd();
	glBegin(GL_TRIANGLES);
	glVertex2f(0, 0.8);
	glVertex2f(0.4, 0.8);
	glVertex2f(0, 0.5);
	glEnd();
	*/




	glFlush();//刷新命令队列和缓存区,使所有尚未执行的OpenGL命令得到执行
}

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR 						lpCmdLine, int nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
	char *argv[] = { "hello "," " };
	int argc = 2;
	glutInit(&argc, argv);    //初始化GLUT库;
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);   //设置显示模式;(缓冲,颜色类型)
	glutInitWindowSize(300, 300);//绘制窗口大小
	glutInitWindowPosition(1024 / 2 - 250, 768 / 2 - 250);//窗口左上角在屏幕的位置
	glutCreateWindow("hello");  //创建窗口,标题为“hello”;
	glutDisplayFunc(display);  //显示回调函数用于绘制当前窗口;
	glutIdleFunc(myidle);
	glutMainLoop();   //表示开始运行程序,用于程序的结尾;
	return 0;
}

 

你可能感兴趣的:(OpenGL)