计算机图形学——实验二 几何图形变换实验
实验二 几何图形变换实验
一、实验目的和要求
- 进一步掌握二维、三维变换的数学知识、变换原理、变换种类、变换方法;
- 利用OpenGL实现二维、三维图形变换,在屏幕上显示变换过程或变换结果;
- 掌握OpenGL常用的变换函数,利用OpenGL绘制简单的三维物体。
二、实验内容
1、下面的代码采用GLUT库,使用了双缓存,在按下鼠标左键后,程序在空闲时一直不停地调用spinDisplay函数,实现了一个矩形在窗口中匀速转动(单击鼠标右键停止转动)。请修改代码,实现矩形在窗口内沿着水平线从左侧移动到右侧。通过实验说明glPushMatrix()和glPopMatrix()的作用。
/*
* double.c
* This is a simple double buffered program.
* Pressing the left mouse button rotates the rectangle.
* Pressing the right mouse button stops the rotation.
*/
#include <GL/glut.h>
#include <stdlib.h>
static GLfloat spin = 0.0;
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(spin, 0.0, 0.0, 1.0);
glColor3f(1.0, 1.0, 1.0);
glRectf(-10.0, -10.0, 10.0, 10.0);
glPopMatrix();
glutSwapBuffers(); //交换双缓存
}
void spinDisplay(void)
{
spin = spin + 2.0;
if (spin > 360.0)
spin = spin - 360.0;
glutPostRedisplay(); //屏幕重绘
}
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void reshape(int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0); //平行投影
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mouse(int button, int state, int x, int y)
{
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(spinDisplay); //设备空闲时调用的函数
break;
case GLUT_MIDDLE_BUTTON:
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(NULL);
break;
default:
break;
}
}
/*
* Request double buffer display mode.
* Register mouse input callback functions
*/
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); //使用双缓存模式
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display); //注册重绘函数
glutReshapeFunc(reshape); //注册改变窗口形状函数
glutMouseFunc(mouse); //注册鼠标动作函数
glutMainLoop();
}
2. 已知某三角形的三顶点坐标{50.0,50.0},{150.0,50.0},{100.0,150.0}。
要求:(1)创建一个长宽分别为600、600的窗口,窗口的左上角位于屏幕坐标(100,100)处。
(2)绘制一个由上述顶点所描绘的三角形,使得三角形位于窗口的中心;对三角形进行下列的几何变换:首先使三角形沿着其中心的x轴,y轴方向缩小到原来的25%;然后绕中心旋转-90度;最后沿着x轴平移70个单位,绘制出变换后的结果。
3. 绘制一个椅子的透视投影图,并使椅子旋转起来,通过鼠标或键盘控制旋转的方向。
参考函数:glutSolidCube(size)绘制实心立方体/glutWireCube(size)绘制线框立方体
这两个函数分别用于绘制中心位于世界坐标系原点的实心立方体和线框立方体,立方体的半径为size,size是一个双精度浮点值。
参考代码: wireobject
三、实验设计思路
1. 创建一个OpenGL工程,修改上述初始化代码display函数,将旋转glRotatef()函数修改成平移变换函数glTranslatef(),再修改一下初始位置。
2. 将上述代码进行鼠标交互等函数的清除,删减后类似与实验一中的代码。修改main函数中的窗口大小和窗口位置。主要修改display函数,glBegin(GL_TRIANGLES);开始画三角形,输入三个点glEnd绘制完成,用平移函数glTranslated、旋转函数glRotated、比例变换函数glScaled,进行从后往前的变换。最后重新绘制原来的三角形。
3. 先绘制一个桌子腿,再将椅子的整体绘制出来,利用的是glutWireCube(size)绘制线框立方体函数,最后通过平移、旋转、缩放函数将椅子在固定位置旋转起来。其中鼠标右键是停止旋转,鼠标左键是继续旋转,鼠标滚轮按钮是控制椅子的旋转方向。
四、实验代码
1.
/** double.c* This is a simple double buffered program.* Pressing the left mouse button rotates the rectangle.* Pressing the right mouse button stops the rotation.*/
#include <GL/glut.h>
#include <stdlib.h>static GLfloat spin = 0.0;void display(void)
{glClear(GL_COLOR_BUFFER_BIT);glPushMatrix();//glRotatef(spin, 0.0, 0.0, 1.0);glTranslatef(spin, 0.0, 0.0);glColor3f(1.0, 1.0, 1.0);glRectf(-50.0, -10.0, -30.0, 10.0);glPopMatrix();glutSwapBuffers(); //交换双缓存
}void spinDisplay(void)
{spin = spin + 0.03;if (spin > 360.0)spin = spin - 360.0;glutPostRedisplay(); //屏幕重绘}void init(void)
{glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_FLAT);
}void reshape(int w, int h)
{glViewport(0, 0, (GLsizei)w, (GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0); //平行投影glMatrixMode(GL_MODELVIEW);glLoadIdentity();
}void mouse(int button, int state, int x, int y)
{switch (button) {case GLUT_LEFT_BUTTON:if (state == GLUT_DOWN)glutIdleFunc(spinDisplay); //设备空闲时调用的函数break;case GLUT_MIDDLE_BUTTON:case GLUT_RIGHT_BUTTON:if (state == GLUT_DOWN)glutIdleFunc(NULL);break;default:break;}
}/** Request double buffer display mode.* Register mouse input callback functions*/
void main(int argc, char** argv)
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); //使用双缓存模式glutInitWindowSize(500, 500);glutInitWindowPosition(100, 100);glutCreateWindow(argv[0]);init();glutDisplayFunc(display); //注册重绘函数glutReshapeFunc(reshape); //注册改变窗口形状函数glutMouseFunc(mouse); //注册鼠标动作函数glutMainLoop();
}
2.
/** double.c* This is a simple double buffered program.* Pressing the left mouse button rotates the rectangle.* Pressing the right mouse button stops the rotation.*/
#include <GL/glut.h>
#include <stdlib.h>void display(void)
{glClear(GL_COLOR_BUFFER_BIT);glPushMatrix(); //操作矩阵堆栈,调用函数,相当于把矩阵放到堆栈上glBegin(GL_TRIANGLES);glVertex2f(50, 50);glVertex2f(150, 50);glVertex2f(100, 150);glEnd();glFlush();glColor3f(1.0f, 1.0f, 1.0f);glTranslated(100, 100, 0);glTranslated(70, 0, 0);glRotated(-90, 0, 0, 1);glScaled(0.25, 0.25, 0.0);glTranslated(-100, -100, 0);glBegin(GL_TRIANGLES);glVertex2f(50, 50);glVertex2f(150, 50);glVertex2f(100, 150);glEnd();glFlush();glPopMatrix();}void init(void)
{glMatrixMode(GL_PROJECTION); //设置投影参数glLoadIdentity();gluOrtho2D(0.0, 200.0, 0.0, 200.0);
}/** Request double buffer display mode.* Register mouse input callback functions*/
void main(int argc, char** argv)
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_RGB); //使用双缓存模式glutInitWindowSize(600, 600);glutInitWindowPosition(100, 100);glutCreateWindow(argv[0]);init();glutDisplayFunc(display); //注册重绘函数//glutReshapeFunc(reshape); //注册改变窗口形状函数//glutMouseFunc(mouse); //注册鼠标动作函数glutMainLoop();
}
3.
#include <GL/glut.h>
float size = 0.25; //缩放
float fTranslate;
float fRotate;
float fScale = 1.0f; // set inital scale value to 1.0f
float K = 1.0f;
float x = 1, y = 0, z = 0;
void Draw_Leg() // This function draws one of the table leg
{//绘制一个桌子腿glPushMatrix();glScalef(1.0f, 1.0f, 3.0f);glutWireCube(1.0 * size);glPopMatrix();}
void Draw_Table() // This function draws a Table
{glPushMatrix(); //将当前矩阵保存入堆栈顶(保存当前矩阵)。glScalef(5.0f, 4.0f, 1.0f); //缩放函数glColor3f(1.0, 0.0, 1.0);glutSolidCube(1 * size); //绘制线立方体glPopMatrix(); //pop出来glPushMatrix(); //将当前矩阵保存入堆栈顶(保存当前矩阵)。glScalef(4.0f, 1.0f, 4.0f); //缩放函数glTranslatef(0.0 * size, 1.5 * size, 0.5 * size);glColor3f(0.0, 0.0, 1.0);glutSolidCube(1 * size); //绘制线立方体glPopMatrix(); //pop出来glPushMatrix(); //左下角的柱子glTranslatef(-1.5 * size, -1 * size, -1.5 * size); //尺寸是相对于中心的坐标原点,按照实验指导上的大小进行的Draw_Leg();glPopMatrix();glPushMatrix(); //右下角的柱子glTranslatef(1.5 * size, -1 * size, -1.5 * size);Draw_Leg();glPopMatrix();glPushMatrix(); //右上角的柱子glTranslatef(1.5 * size, 1 * size, -1.5 * size);Draw_Leg();glPopMatrix();glPushMatrix(); //左上角的柱子glTranslatef(-1.5 * size, 1 * size, -1.5 * size);Draw_Leg();glPopMatrix();}
void reshape(int width, int height)
{if (height == 0) // Prevent A Divide By Zero By{height = 1; // Making Height Equal One}glViewport(0, 0, width, height); // Reset The Current ViewportglMatrixMode(GL_PROJECTION); // Select The Projection MatrixglLoadIdentity(); // Reset The Projection Matrix// Calculate The Aspect Ratio Of The WindowgluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);glMatrixMode(GL_MODELVIEW); // Select The Modelview MatrixglLoadIdentity(); // Reset The Modelview Matrix
}void idle()
{glutPostRedisplay();
}void redraw()
{// If want display in wireframe mode//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);glClear(GL_COLOR_BUFFER_BIT); //当前缓冲区清除值,这里是清除颜色缓冲glLoadIdentity(); // Reset The Current Modelview Matrixif (K == 1){glPushMatrix();glTranslatef(-1.0f, 0.0f, -6.0f); // Place the triangle at CenterglRotatef(fRotate * K, x, y, z); // Rotate around Y axisDraw_Table(); // Draw triangleglPopMatrix();glPushMatrix();glTranslatef(1.0f, 0.0f, -6.0f);glRotatef(fRotate * K, y, x, z);Draw_Table();glPopMatrix();fRotate += 0.05f;}else if (K == 0) {glPushMatrix();glTranslatef(-1.0f, 0.0f, -6.0f); // Place the triangle at CenterglRotatef(fRotate, x, y, 0); // Rotate around Y axisDraw_Table(); // Draw triangleglPopMatrix();glPushMatrix();glTranslatef(1.0f, 0.0f, -6.0f);glRotatef(fRotate, y, x, z);Draw_Table();glPopMatrix();}glutSwapBuffers();
}void myMouse(int button, int state, int x, int y) {if (state == GLUT_DOWN){if (button == GLUT_LEFT_BUTTON){K = 1;}else if (button == GLUT_RIGHT_BUTTON){K = 0;}}}void processMenuEvents_two(int option) {switch (option){case 1:x = 1; y = 0; z = 0; break;case 2:x = 0; y = 1; z = 0; break;case 3:x = 0; y = 0; z = 1; break;default:break;}
}
int main(int argc, char* argv[])
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);glutInitWindowSize(640, 480);int windowHandle= glutCreateWindow("Simple GLUT App");glutDisplayFunc(redraw);glutReshapeFunc(reshape);glutIdleFunc(idle);glutMouseFunc(myMouse);//鼠标滚轮glutCreateMenu(processMenuEvents_two);glutAddMenuEntry("X", 1);glutAddMenuEntry("Y", 2);glutAddMenuEntry("Z", 3);glutAttachMenu(GLUT_MIDDLE_BUTTON);glutMainLoop();return 0;
}
五、实验结果及心得体会
1.
2.
3.
此次实验,进一步掌握二维、三维变换的数学知识、变换原理、变换种类及变换方法;使用了OpenGL利用常用的变换函数实现了二维、三维图形变换;同时还绘制了一个简单的三维立体图形。通过本次实验,进一步学习了图形学中的几何图形知识以及变换过程,收获颇多,对今后本课程的学习有了较大的帮助。
计算机图形学——实验二 几何图形变换实验相关推荐
- 20175212童皓桢 Java实验二-面向对象程序设计实验报告
20175212童皓桢 Java实验二-面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设 ...
- 计算机图形学基础1——MVP变换
参考链接: 线性变换 计算机图形学入门教程 视图变换 图形学随笔:MVP变换-视图变换 计算机图形学笔记-专栏 View/Camera Transformation视图变换 MVP变换: 我们知道我们 ...
- 【通信原理】实验二 角度调制实验
目录 实验二 角度调制实验 一.实验目的 二.实验原理: 1.角度调制 (1)角度调制 (1)频率调制(FM): (2)相位调制(PM) (3)单音调制FM与PM (4)非相干解调 2.MATLAB中 ...
- 【计算机图形学】小白谈计算机图形学(二)画圆篇之中点画圆法,Bresenham画圆算法,椭圆实操,线型处理详解
小白谈计算机图形学(二)画圆篇之中点画圆法,Bresenham画圆算法,椭圆实操,线型处理详解 引言 如何画圆 基本思想 中点画圆法 中点画圆基本思路 中点画圆改进 Bresenham画圆算法 Bre ...
- 计算机图形学笔记(观测变换、模型变换、视图变换、投影变换、视口变换)
计算机图形学笔记(观测变换.模型变换.视图变换.投影变换.视口变换) 目录 计算机图形学笔记(观测变换.模型变换.视图变换.投影变换.视口变换) 一.简介 1.模型变换(Model transform ...
- 20172310《程序设计与数据结构》(下)实验二:二叉树实验报告
20172310<程序设计与数据结构>(下)实验二:二叉树实验报告 报告封面 课程:<软件结构与数据结构> 班级: 1723 姓名: 仇夏 学号:20172310 实验教师:王 ...
- matlab建立二阶开环系统仿真图,实验二 Simulink仿真实验
实验二 Simulink仿真实验 一. 实验目的: 1.学会使用Matlab软件中的Simulink仿真工具. 2.了解二阶系统瞬态响应指标的意义其计算. 二. 实验内容及原理 1. 用Matlab仿 ...
- CSAPP实验二——bomb lab实验
CSAPP实验二-- bomb lab实验 实验前准备 第一部分(phase_1) 第二部分(phase_2) 第三部分(phase_3) 第四部分(phase_4) 第五部分(phase_5) 第六 ...
- 嵌入式系统 实验二 串口通信实验
实验二 串口通信实验 一.实验目的 1.)了解 USART 的基本特性: 2.)掌握用库函数操作 USART 的方法: 3.)掌握如何使用 STM32 的串口发送和接收数据. 二.实验环境 1.)硬件 ...
最新文章
- HDU 6264 Super-palindrome
- SpringBoot的优势
- Anaconda3自带jupyter
- linux 硬盘响,完美解决Ubuntu Linux关机异响[SATA硬盘]
- Flyway 数据库版本管理控制
- 系统集成项目管理工程师笔记
- Minitab正态能力分析算法资源合集
- 老码农的2019这一年——
- 浸没式液冷,阿里云新立项两大技术白皮书
- ei会议和ei源刊的区别_ei会议和ei期刊的区别
- MySQL查询效率问题
- 中国移动DNS IP地址大全(32个省)
- php 深度验证18位身份证是否正确,并获取地址,出生日期(时间戳),性别。
- 《炬丰科技-半导体工艺》晶片键合技术和薄膜传输技术
- c语言 cdma编码正交的8位码片,关于码分多址CDMA正交码片序列的进一步说明
- python 随机生成手机号码_Python实现随机创建电话号码的方法示例
- 百度网盘被和谐文件一键清理不能下载违规信息空间删除
- Vue结合element-ui实现导航菜单展开收缩小功能
- 在Unity环境中使用强化学习训练Donkey Car(转译)
- ghost-theme-mj主题简介