计算机图形学报告2
西安电子科技大学
计算机图形学 课程实验报告
实验名称 第2次上机实验
计算机 学院 1803012 班
姓名 曹王欣 学号 18030100167
同作者
实验日期 2020 年 月 日
实验地点 实验批次
指导教师评语:
指导教师: 年 月 日 |
实验报告内容基本要求及参考格式 一、实验目的 二、实验所用仪器(或实验环境) 三、实验基本原理及步骤(或方案设计及理论计算) 四、实验数据记录(或仿真及软件设计) 五、实验结果分析及回答问题(或测试环境及测试结果) |
- 图形变换(借鉴lec4课件)
1. 利用OpenGL实现一个立方体关于参考点(10.0,20.0,10.0)进行放缩变换,放缩因子为(2.0,1.0,0.5)。
2. 利用OpenGL实现一个矩形关于y=x+5对称的新图形。
3. 通过定义键盘回调函数,每按一次空格键,让三个点依次完成画点、画线、画三角形,并让三角形沿三角形中心旋转起来。
一.针对题目1
核心代码就是
glTranslatef(10.0, 20.0, 10.0); //沿x平移10,y轴正方向移动20个单位,z轴10,最后的矩阵反而最先指定
glScalef(2, 1, 0.5);
glTranslatef(-10, -20,-10);
这三行代码,用于确定我们的放缩矩阵
我的实现如下:
#include <GL/glut.h>
void init()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
}
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(45.0, 1.0, 1.0, 1.0);//绕着向量(1,1,1)所指定的轴旋转45°,为了观察方便
glutWireCube(10.0);
glLoadIdentity();//初始化矩阵状态
glColor3f(0.0, 0.0, 1.0);
glTranslatef(10.0, 20.0, 10.0); //沿x平移10,y轴正方向移动20个单位,z轴10,最后的矩阵反而最先指定
glScalef(2, 1, 0.5);
glTranslatef(-10, -20,-10);
glRotatef(45.0, 1.0, 1.0, 1.0);//绕着向量(1,1,1)所指定的轴旋转45°,为了观察方便
glutWireCube(10.0);
glFlush();
}
void ChangeSize(GLsizei w, GLsizei h)
{
GLfloat aspectRatio;
if (h == 0)
h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
aspectRatio = (GLfloat)w / (GLfloat)h;
if (w <= h)
glOrtho(-50.0, 50.0, -50.0 / aspectRatio, 50.0 / aspectRatio, -50.0, 50.0);
else
glOrtho(-50.0 * aspectRatio, 50.0 * aspectRatio, -50.0, 50.0, -50.0, 50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc,char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutCreateWindow("Cube");
init();
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
实验截图如下(为了观察方便,我画图的时候把立方体转了一个角度,可以看到红色的原来的图形和蓝色的后来的图形):
实验2的实现如下:
最重要的代码是以下五行,这里确定了变换矩阵,方法是先把直线平移过原点,然后把它旋转-45度与x轴重合,然后翻转,最后再变换回原来的地方就行了
glTranslatef(0,5,0);
glRotatef(45,0,0,1);
glScalef(1,-1,0);
glRotatef(-45,0,0,1);
glTranslatef(0,-5,0);
具体代码实现如下:
#include <GL/glut.h>
void init()
{
glClearColor(1, 1, 1, 1);
}
void ChangeSize(GLsizei w, GLsizei h)
{
GLfloat aspectRatio;
if (h == 0)
h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
aspectRatio = (GLfloat)w / (GLfloat)h;
if (w <= h)
glOrtho(-50.0, 50.0, -50.0 / aspectRatio, 50.0 / aspectRatio, -50.0, 50.0);
else
glOrtho(-50.0 * aspectRatio, 50.0 * aspectRatio, -50.0, 50.0, -50.0, 50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0, 0, 1);//先画对称轴
glBegin(GL_LINES);
glVertex3f(-5, 0, 0);
glVertex3f(20, 25, 0);
glEnd();
glColor3f(1, 0, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRecti(0, 0, 15, 5);//一开始的矩形
glTranslatef(0,5,0);
glRotatef(45,0,0,1);
glScalef(1,-1,0);
glRotatef(-45,0,0,1);
glTranslatef(0,-5,0);
glRecti(0, 0, 15, 5);//最后变换的矩形
glFlush();
}
int main(int argc,char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutCreateWindow("Cube");
init();
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
实验结果如下:
可以看到,我们实现了关于y=x+5的对称,蓝色的那条线是我画出来的对称轴,我画了两个红色的矩形,发现他们是对称的
实验3的实现如下:
核心的键盘响应代码如下:
void myKey(unsigned char key, int x, int y) //响应ASCII对应键,鼠标的当前x和y位置也被返回。
{
switch (key)
{
case ' ': currentMode = (currentMode + 1) % ModeNums;
if (currentMode == 4)
glutIdleFunc(rotatehex);
else if (currentMode == 5)
glutIdleFunc(NULL);
else
glutPostRedisplay(); //告诉GLUT刷新当前窗口
break;
case 27: exit(-1);
}
}
其中我设定一开始画点,然后currentMode+1之后,画折线,然后画空的三角形,然后是填充的三角形,最后是旋转的三角形,这里我使用双缓存,然后注意要交换缓冲区,使用了glutSwapBuffers();
全部代码如下:
#include"windows.h"
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
int currentMode = 0;
const int ModeNums = 6;
void init()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
}
float rotheta = 0;
void rotatehex(void)
{
rotheta += 3;
if (rotheta > 360)
rotheta -= 360;
glutPostRedisplay();
}
void myKey(unsigned char key, int x, int y) //响应ASCII对应键,鼠标的当前x和y位置也被返回。
{
switch (key)
{
case ' ': currentMode = (currentMode + 1) % ModeNums;
if (currentMode == 4)
glutIdleFunc(rotatehex);
else if (currentMode == 5)
glutIdleFunc(NULL);
else
glutPostRedisplay(); //告诉GLUT刷新当前窗口
break;
case 27: exit(-1);
}
}
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT);
switch (currentMode)
{
case 0: glPointSize(5);
glBegin(GL_POINTS);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(3.0, 3.0);
glVertex2f(8.0, 3.0);
glVertex2f(5.0, 8.0);
glEnd();
break;
case 1: glBegin(GL_LINE_STRIP);
glColor3f(0.0, 1.0, 0.0);
glVertex2f(3.0, 3.0);
glVertex2f(8.0, 3.0);
glVertex2f(5.0, 8.0);
glEnd();
break;
case 2: glBegin(GL_LINE_LOOP);
glColor3f(0.0, 0.0, 1.0);
glVertex2f(3.0, 3.0);
glVertex2f(8.0, 3.0);
glVertex2f(5.0, 8.0);
glEnd();
break;
case 3: glBegin(GL_TRIANGLES);
glColor3f(1.0, 1.0, 0.0);
glVertex2f(3.0, 3.0);
glVertex2f(8.0, 3.0);
glVertex2f(5.0, 8.0);
glEnd();
break;
case 4:
glMatrixMode(GL_MODELVIEW);
glTranslatef(16 / 3, 14 / 3, 0);
glRotatef(rotheta, 0, 0, 1);
glTranslatef(-16 / 3, -14 / 3, 0);
glBegin(GL_TRIANGLES);
glColor3f(0, 1, 1);
glVertex2f(3.0, 3.0);
glVertex2f(8.0, 3.0);
glVertex2f(5.0, 8.0);
glEnd();
case 5:
glBegin(GL_TRIANGLES);
glColor3f(0, 1, 1);
glVertex2f(3.0, 3.0);
glVertex2f(8.0, 3.0);
glVertex2f(5.0, 8.0);
glEnd();
}
glutSwapBuffers();
glFlush();
}
void ChangeSize(GLsizei w, GLsizei h)
{
float ratio;
if (h == 0)
h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
ratio = (float)w / (float)h;
if (w <= h)
gluOrtho2D(0.0, 10.0, 0.0 / ratio, 10.0 / ratio);
else
gluOrtho2D(0.0 * ratio, 10.0 * ratio, 0.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc,char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(50, 50);
glutInitWindowSize(360, 360);
glutCreateWindow("KeyboardFunc");
init();
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutKeyboardFunc(myKey); //为当前窗口设置键盘回调函数。
printf("Press space to continue,press escape to exit!\n");
glutMainLoop();
return 0;
}
实验结果的截图如下,分别对应点,折现,空心三角形,填充三角形,最后把三角形转起来(旋转的三角形没办法截图,老师运行下程序就知道了):