实验三 几何图形变换实验
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
glLoadIdentity ();
glColor3f (1.0, 1.0, 1.0);
draw_triangle ();
glEnable (GL_LINE_STIPPLE);
glLineStipple (1, 0xF0F0);
glLoadIdentity ();
glTranslatef (-20.0, 0.0, 0.0);
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);//使用双缓存模式
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
4.投影变换
1)OpenGL平行投影函数共有两个:
一个函数是:
void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble near,GLБайду номын сангаасouble far)
它创建一个平行视景体。实际上这个函数的操作是创建一个平行投影矩阵,并且用这个矩阵乘以当前矩阵。其中近裁剪平面是一个矩形,矩形左下角点三维空间坐标是(left,bottom,-near),右上角点是(right,top,-near);远裁剪平面也是一个矩形,左下角点空间坐标是(left,bottom,-far),右上角点是(right,top,-far)。所有的near和far值同时为正或同时为负。如果没有其他变换,正射投影的方向平行于Z轴,且视点朝向Z负轴。
另一个函数是:
void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar);
它也创建一个对称透视视景体,但它的参数定义于前面的不同。其操作是创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵。参数fovy定义视野在X-Z平面的角度,范围是[0.0,180.0];参数aspect是投影平面宽度与高度的比率;参数zNear和Far分别是远近裁剪面沿Z负轴到视点的距离,它们总为正值。
if (state == GLUT_DOWN)
glutIdleFunc(NULL);
break;
default:
break;
}
}
/*
* Request double buffer display mode.
* Register mouse input callback functions
*/
int main(int argc, char** argv)
glLoadIdentity ();
if (w <= h)
gluOrtho2D(-50.0, 50.0, -50.0*(GLfloat)h/(GLfloat)w,
50.0*(GLfloat)h/(GLfloat)w);
else
gluOrtho2D(-50.0*(GLfloat)w/(GLfloat)h,
1.平移变换
平移变换函数如下:
void glTranslate {fd} (TYPE x, TYPE y, TYPE z);
三个函数参数就是目标分别沿三个轴向平移的偏移量。这个函数表示用这三个偏移量生成的矩阵乘以当前矩阵。
2.旋转变换
旋转变换函数如下:
void glRotate {fd} (TYPE angle, TYPE x, TYPE y, TYPE z);
draw_triangle ();
glDisable (GL_LINE_STIPPLE);
glFlush ();
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
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);
return 0;
}
3. 绘制一个三棱椎的透视投影图,要求:实现匀速旋转(提示:参考题目1,使用双缓存模式);改变变换方式,达到不同的效果。
glPopMatrix();
glutSwapBuffers();//交换双缓存
}
void spinDisplay(void)
{
spin = spin + 2.0;
if (spin > 360.0)
spin = spin - 360.0;
glutPostRedisplay();
}
void init(void)
glVertex2f(0.0, 25.0);
glVertex2f(25.0, -25.0);
glVertex2f(-25.0, -25.0);
glEnd();
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
这意味着物体在视点前面时far和near都为负值,物体在视点后面时far和near都为正值。
另一个函数是:
void gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top)
它是一个特殊的正射投影函数,主要用于二维图像到二维屏幕上的投影。它的near和far缺省值分别为-1.0和1.0,所有二维物体的Z坐标都为0.0。因此它的裁剪面是一个左下角点为(left,bottom)、右上角点为(right,top)的矩形。
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)
* Pressing the left mouse button rotates the rectangle.
* Pressing therightmouse button stops the rotation.
*/
#include <GL/glut.h>
#include <stdlib.h>
static GLfloat spin = 0.0;
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
三、实验内容
1、下面的代码采用GLUT库,使用了双缓存,在按下鼠标左键后,程序在空闲时一直不停地调用spinDisplay函数,实现了一个矩形在窗口中匀速转动(单击鼠标右键停止转动)。请修改代码,实现矩形在窗口内沿着水平线移动。
/*
* double.c
* This is a simple double buffered program.
draw_triangle ();
glLineStipple (1, 0xF00F);
glLoadIdentity ();
glScalef (1.5, 0.5, 1.0);
draw_triangle ();
glLineStipple (1, 0x8888);
glLoadIdentity ();
glRotatef (90.0, 0.0, 0.0, 1.0);
50.0*(GLfloat)w/(GLfloat)h, -50.0, 50.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
2)OpenGL透视投影函数共有两个:
void glFrustum(GLdouble left,GLdouble Right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);
它创建一个透视视景体。其操作是创建一个透视投影矩阵,并且用这个矩阵乘以当前矩阵。这个函数的参数只定义近裁剪平面的左下角点和右上角点的三维空间坐标,即(left,bottom,-near)和(right,top,-near);最后一个参数far是远裁剪平面的Z负值,其左下角点和右上角点空间坐标由函数根据透视投影原理自动生成。near和far表示离视点的远近,它们总为正值。
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
2. 已知某三角形的三顶点坐标{50.0,25.0},{150.0,25.0},{100.0,100.0}。
{
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(spinDisplay);//设备空闲时调用的函数
break;
case GLUT_MIDDLE_BUTTON:
case GLUT_RIGHT_BUTTON:
函数中第一个参数是表示目标沿从点(x, y, z)到原点的方向逆时针旋转的角度,后三个参数是旋转的方向点坐标。这个函数表示用这四个参数生成的矩阵乘以当前矩阵。
3.比例变换
比例变换函数如下:
void glScale {fd} (TYPE x, TYPE y, TYPE z);
三个函数参数值就是目标分别沿三个轴向缩放的比例因子。这个函数表示用这三个比例因子生成的矩形乘以当前矩阵。这个函数能完成沿相应的轴对目标进行拉伸、压缩和反射三项功能。以参数x为例,若当x大于1.0时,表示沿x轴方向拉伸目标;若x小于1.0时,表示沿x轴方向收缩目标;若x=-1.0表示沿x轴反射目标。
{
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);
参考代码:
#include <GL/glut.h>
#include <stdlib.h>
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void draw_triangle(void)
{
glBegin (GL_LINE_LOOP);
要求:(1)创建一个长宽分别为600、600的窗口,窗口的左上角位于屏幕坐标(100,100)处。(提示:请试着修改gluOrtho2D函数参数,使得绘制的三角形尽可能居中显示)
(2)绘制一个由上述顶点所描绘的三角形,实现该三角形进行下列的几何变化:首先使三角形沿着其中心的x轴,y轴方向缩小50%;然后沿着初始中心旋转90度;最后沿着y轴平移100个单位。
实验三
实验项目性质:设计性实验
所属课程名称:3D游戏图形学
实验计划学时:3学时
一、实验目的和要求
1.进一步掌握二维、三维变换的数学知识、变换原理、变换种类、变换方法;
2.利用OpenGL实现二维、三维图形变换,在屏幕上显示变换过程或变换结果;
3.掌握OpenGL常用的变换函数。
二、实验原理
OpenGL的三个基本几何变换函数介绍如下:
glColor3f (1.0, 1.0, 1.0);
draw_triangle ();
glEnable (GL_LINE_STIPPLE);
glLineStipple (1, 0xF0F0);
glLoadIdentity ();
glTranslatef (-20.0, 0.0, 0.0);
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);//使用双缓存模式
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
4.投影变换
1)OpenGL平行投影函数共有两个:
一个函数是:
void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble near,GLБайду номын сангаасouble far)
它创建一个平行视景体。实际上这个函数的操作是创建一个平行投影矩阵,并且用这个矩阵乘以当前矩阵。其中近裁剪平面是一个矩形,矩形左下角点三维空间坐标是(left,bottom,-near),右上角点是(right,top,-near);远裁剪平面也是一个矩形,左下角点空间坐标是(left,bottom,-far),右上角点是(right,top,-far)。所有的near和far值同时为正或同时为负。如果没有其他变换,正射投影的方向平行于Z轴,且视点朝向Z负轴。
另一个函数是:
void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar);
它也创建一个对称透视视景体,但它的参数定义于前面的不同。其操作是创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵。参数fovy定义视野在X-Z平面的角度,范围是[0.0,180.0];参数aspect是投影平面宽度与高度的比率;参数zNear和Far分别是远近裁剪面沿Z负轴到视点的距离,它们总为正值。
if (state == GLUT_DOWN)
glutIdleFunc(NULL);
break;
default:
break;
}
}
/*
* Request double buffer display mode.
* Register mouse input callback functions
*/
int main(int argc, char** argv)
glLoadIdentity ();
if (w <= h)
gluOrtho2D(-50.0, 50.0, -50.0*(GLfloat)h/(GLfloat)w,
50.0*(GLfloat)h/(GLfloat)w);
else
gluOrtho2D(-50.0*(GLfloat)w/(GLfloat)h,
1.平移变换
平移变换函数如下:
void glTranslate {fd} (TYPE x, TYPE y, TYPE z);
三个函数参数就是目标分别沿三个轴向平移的偏移量。这个函数表示用这三个偏移量生成的矩阵乘以当前矩阵。
2.旋转变换
旋转变换函数如下:
void glRotate {fd} (TYPE angle, TYPE x, TYPE y, TYPE z);
draw_triangle ();
glDisable (GL_LINE_STIPPLE);
glFlush ();
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
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);
return 0;
}
3. 绘制一个三棱椎的透视投影图,要求:实现匀速旋转(提示:参考题目1,使用双缓存模式);改变变换方式,达到不同的效果。
glPopMatrix();
glutSwapBuffers();//交换双缓存
}
void spinDisplay(void)
{
spin = spin + 2.0;
if (spin > 360.0)
spin = spin - 360.0;
glutPostRedisplay();
}
void init(void)
glVertex2f(0.0, 25.0);
glVertex2f(25.0, -25.0);
glVertex2f(-25.0, -25.0);
glEnd();
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
这意味着物体在视点前面时far和near都为负值,物体在视点后面时far和near都为正值。
另一个函数是:
void gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top)
它是一个特殊的正射投影函数,主要用于二维图像到二维屏幕上的投影。它的near和far缺省值分别为-1.0和1.0,所有二维物体的Z坐标都为0.0。因此它的裁剪面是一个左下角点为(left,bottom)、右上角点为(right,top)的矩形。
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)
* Pressing the left mouse button rotates the rectangle.
* Pressing therightmouse button stops the rotation.
*/
#include <GL/glut.h>
#include <stdlib.h>
static GLfloat spin = 0.0;
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
三、实验内容
1、下面的代码采用GLUT库,使用了双缓存,在按下鼠标左键后,程序在空闲时一直不停地调用spinDisplay函数,实现了一个矩形在窗口中匀速转动(单击鼠标右键停止转动)。请修改代码,实现矩形在窗口内沿着水平线移动。
/*
* double.c
* This is a simple double buffered program.
draw_triangle ();
glLineStipple (1, 0xF00F);
glLoadIdentity ();
glScalef (1.5, 0.5, 1.0);
draw_triangle ();
glLineStipple (1, 0x8888);
glLoadIdentity ();
glRotatef (90.0, 0.0, 0.0, 1.0);
50.0*(GLfloat)w/(GLfloat)h, -50.0, 50.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
2)OpenGL透视投影函数共有两个:
void glFrustum(GLdouble left,GLdouble Right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);
它创建一个透视视景体。其操作是创建一个透视投影矩阵,并且用这个矩阵乘以当前矩阵。这个函数的参数只定义近裁剪平面的左下角点和右上角点的三维空间坐标,即(left,bottom,-near)和(right,top,-near);最后一个参数far是远裁剪平面的Z负值,其左下角点和右上角点空间坐标由函数根据透视投影原理自动生成。near和far表示离视点的远近,它们总为正值。
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
2. 已知某三角形的三顶点坐标{50.0,25.0},{150.0,25.0},{100.0,100.0}。
{
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(spinDisplay);//设备空闲时调用的函数
break;
case GLUT_MIDDLE_BUTTON:
case GLUT_RIGHT_BUTTON:
函数中第一个参数是表示目标沿从点(x, y, z)到原点的方向逆时针旋转的角度,后三个参数是旋转的方向点坐标。这个函数表示用这四个参数生成的矩阵乘以当前矩阵。
3.比例变换
比例变换函数如下:
void glScale {fd} (TYPE x, TYPE y, TYPE z);
三个函数参数值就是目标分别沿三个轴向缩放的比例因子。这个函数表示用这三个比例因子生成的矩形乘以当前矩阵。这个函数能完成沿相应的轴对目标进行拉伸、压缩和反射三项功能。以参数x为例,若当x大于1.0时,表示沿x轴方向拉伸目标;若x小于1.0时,表示沿x轴方向收缩目标;若x=-1.0表示沿x轴反射目标。
{
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);
参考代码:
#include <GL/glut.h>
#include <stdlib.h>
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void draw_triangle(void)
{
glBegin (GL_LINE_LOOP);
要求:(1)创建一个长宽分别为600、600的窗口,窗口的左上角位于屏幕坐标(100,100)处。(提示:请试着修改gluOrtho2D函数参数,使得绘制的三角形尽可能居中显示)
(2)绘制一个由上述顶点所描绘的三角形,实现该三角形进行下列的几何变化:首先使三角形沿着其中心的x轴,y轴方向缩小50%;然后沿着初始中心旋转90度;最后沿着y轴平移100个单位。
实验三
实验项目性质:设计性实验
所属课程名称:3D游戏图形学
实验计划学时:3学时
一、实验目的和要求
1.进一步掌握二维、三维变换的数学知识、变换原理、变换种类、变换方法;
2.利用OpenGL实现二维、三维图形变换,在屏幕上显示变换过程或变换结果;
3.掌握OpenGL常用的变换函数。
二、实验原理
OpenGL的三个基本几何变换函数介绍如下: