计算机图形学习题

来源:互联网 发布:广西南宁智尚网络骗局 编辑:程序博客网 时间:2024/06/04 00:51


1:请简述计算机图形学的应用领域。

   答:真实感图形、科学计算可视化、虚拟环境、多媒体技术、计算机动画、

       计算机辅助工程制图等领域。

2:名称解释:何谓刷新频率? 何谓分辨率? 何谓像素? 何谓图元?

   答:刷新频率是指图像在屏幕上更新的速度,也即是在屏幕上重复画图的频率;   

       分辨率:一个CRT在水平和竖直方向单位长度上能识别的最大光点数。

       像数:每个可有电子束点亮的屏幕点

       图元:图形元素,可以编辑的最小图形单位(图形软件包中用来描述各种图形元素的函数)

3:根据三原色原理,一个色彩,其红色分量强度值为1.0,绿色分量强度值为1.0,而蓝色分量强度值为0.0,则该色彩为:

   答:黄色

4:分析如下两种计算机图形系统结构的优劣,并说明优劣的原因。

计算机图形系统结构1

计算机图形系统结构2

结构1为简单光栅图形系统结构

结构2为带有显示处理器的光栅图形系统结构

结构1的优点:

             帧缓存可以存储在系统存储器的任意位置,视频控制器可以通过访问帧缓

             存来刷新屏幕

结构1的缺点:

System memory和帧缓存相当于绑定在一起了

结构2的优点:

            将CPU从复杂的图形处理中脱离出来,提供了独立的的存储器处理区,光栅

            扫描显示系统的架构中包含显示处理器。

结构2的缺点:

     为减少光栅系统中对存储量的需求而采用的行程编码技术对强度的改变难以

            记录,另外当包含许多短行程时,显示控制器处理光栅式困难的。

5:给定如下一段源代码,请分析该代码执行后OpenGL显示窗口内显示的内容。

#include <gl/glut.h>

void showNothing(void)

{

glClearColor(0.0,0.0,1.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

glFlush();

}

void main(int argc, char** argv)

{

glutInit(&argc, argv);

glutCreateWindow("An example OpenGL program");

glutDisplayFunc(showNothing);

glutMainLoop();

}

答:显示填满蓝色的窗口

6:写出将OpenGL显示窗口左上角设定到像素位置(50,100),显示窗口宽度为400像素且高度为300像素的语句。

答: glutInitWindowSize(400,300); 

 glutInitWindowPosition(50,100); 

7:如果下面三段代码被正确的嵌入到一个可以执行的OpenGL绘图框架中,请问在代码段2中绘制的哪些点可以在代码段3中创建的显示窗口中得到显示? 

答:   点(10.0,10.0)和(200.0,200.0)显示

//代码段1

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0.0, 300.0, 0.0, 300.0);

//代码段2

glBegin(GL_POINTS);

glVertex2f(10.0,10.0);

glVertex2f(200.0,200.0);

glVertex2f(400.0,400.0);

glEnd();

//代码段3

glutInitWindowSize(100,100);

glutInitWindowPosition(50,100); 

glutCreateWindow("An example OpenGL program");

8:阅读下面的代码(特别注意粗体部分代码行),分析为什么在显示回调函数showLineSegment中绘制的正方形,结果在显示窗口中看到却是长方形?如果希望在显示回调函数绘制的正方形在显示窗口中仍然显示为正方形,在保证showLineSegment中的代码不变的情况下,该如何处理?

#include <gl/glut.h>

void showLineSegment(void)

{

glClearColor(1.0,1.0,1.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(0.0,0.0,1.0);

glBegin(GL_POLYGON);

glVertex2i(100,100);

glVertex2i(200,100);

glVertex2i(200,200);

glVertex2i(100,200);

glEnd();

glFlush();

}

void adjustRatio(GLsizei w, GLsizei h)

{   

glViewport(0,0,w,h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0.0,300,0.0,300);

}

void main(int argc, char** argv)

{

glutInit(&argc, argv);

glutInitWindowSize(300,600);

glutInitWindowPosition(50,100);

glutCreateWindow("An example OpenGL program");

glutDisplayFunc(showLineSegment);

glutReshapeFunc(adjustRatio);

glutMainLoop();

}

答:将adjustRatio()函数中的gluOrtho2D(0.0,300,0.0,300);改为

     if (w <= h)

gluOrtho2D(0.0,300,0.0,300*h/w);

  else

gluOrtho2D(0.0,300*w/h,0.0,300);

   

9:阅读下面的代码,(1)请简要描述该代码执行后的效果;(2)如果将myIdle函数中的glutPostRedisplay()使用myDisplay()函数替换,能否看到动画效果?(3)如果将myDisplay函数中的glFlush()替换为glutSwapBuffers(),能够看到动画效果?

#include <gl/glut.h>

GLfloat tx = 0.0;

GLfloat ty = 0.0;

void init(void)

{   

glClearColor(0.0,0.0,0.0,0.0);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0.0,300.0,0.0,300.0);

}

void myDisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1.0,0.0,0.0);

glBegin(GL_POLYGON);

glVertex2f(tx,ty);

glVertex2f(20+tx,ty);

glVertex2f(20+tx,20+ty);

glVertex2f(tx,20+ty);

    glEnd();

glFlush();//glutSwapBuffers();

}

void myIdle(void)

{

tx += 0.01;

ty += 0.01;

if (tx>300.0) tx = 0.0;

if (ty>300.0) ty = 0.0;

glutPostRedisplay();//myDisplay();

}

void main(int argc, char** argv)

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

glutInitWindowSize(300,300);

glutInitWindowPosition(300,300);

glutCreateWindow("MultiObject Animation");

init();

glutIdleFunc(myIdle);

glutDisplayFunc(myDisplay);

glutMainLoop();

}

答:

在弹出的黑色背景的窗口中一个红色方块沿对角线移动,循环动画,但由于是单

       缓冲模式,红色小方块不断闪屏

还能看到动画效果

     (3) 如果将myDisplay函数中的glFlush()替换为glutSwapBuffers(),可以看到效果,但不是双缓冲效果

10:在鼠标的交互式控制中,OpenGL可以通过检查按下鼠标的状态来进行相应的控制。阅读如下代码,并分析鼠标左键单击和鼠标右键单击情况下,观察到的程序执行结果有何不同。

#include <gl/glut.h>

#include <windows.h>

GLfloat tx = 0.0;

GLfloat ty = 0.0;

void init(void)

{   

glClearColor(0.0,0.0,0.0,0.0);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0.0,300.0,0.0,300.0);

}

void myIdle(void)

{

tx += 0.01;

ty += 0.01;

if (tx>300.0) tx = 0.0;

if (ty>300.0) ty = 0.0;

glutPostRedisplay();

}

void myMouseClick(int button, int state, int x, int y)

{

if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)

glutIdleFunc(myIdle);

if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)

glutIdleFunc(NULL);

}

void myDisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1.0,0.0,0.0);

glBegin(GL_POLYGON);

glVertex2f(tx,ty);

glVertex2f(20+tx,ty);

glVertex2f(20+tx,20+ty);

glVertex2f(tx,20+ty);

    glEnd();

glutSwapBuffers();

}

void main(int argc, char** argv)

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

glutInitWindowSize(300,300);

glutInitWindowPosition(300,300);

glutCreateWindow("MultiObject Animation");

init();

glutMouseFunc(myMouseClick); 

glutDisplayFunc(myDisplay);

glutMainLoop();

}

 答:按下鼠标左键红色方块就会沿着斜对角线移动,

     按右键就会暂停

11:给定如下三行代码段,试分析最初绘制的黄色长方形所历经的几何变换的秩序。

  glColor3f(1.0,1.0,0.0);

glRotatef(90.0,0.0,0.0,1.0);/旋转

glTranslatef(-100.0,0.0,0.0);//平移

glScalef(0.5,1.0,1.0);//缩放

glRecti(50,100,150,150);//绘制一个黄色长方形

答: 在x方向缩放0.5倍,yz轴方向不变;

     再在x轴方向上平移100个单位;

     最后生成绕z轴旋转90°的图形;

12:给定如下的显示回调函数的代码片段,假定glLoadIdentity()函数定义的矩阵为glTranslatef(50.0,50.0,0.0);定义的矩阵为glRotatef(90.0,0.0,0.0,1.0);定义的矩阵为glTranslatef(-100.0,0.0,0.0);定义的矩阵为glScalef(0.5,1.0,1.0);定义的矩阵为。假定Line 2代码执行后MODELVIEW矩阵堆栈状态为:

试分析Line 5, Line 7, Line 9, Line 10, Line 12, Line 14, Line 16, Line 17每一行代码执行后,MODELVIEW矩阵堆栈状态。

glMatrixMode(GL_MODELVIEW);// Line 1

glLoadIdentity();// Line 2

     

glColor3f(1.0,0.0,0.0); // Line 3

glRecti(50,100,200,150); // Line 4

glPushMatrix();// Line 5

I

I

glColor3f(0.0,1.0,0.0); // Line 6

glTranslatef(50.0,50.0,0.0); // Line 7 

I*T1

I

glRecti(50,100,200,150); // Line 8

glPopMatrix();// Line 9

I

glPushMatrix();// Line 10

I

I

glColor3f(0.0,0.0,1.0); // Line 11

glRotatef(90.0,0.0,0.0,1.0); // Line 12 

I*R1

I

glRecti(50,100,200,150); // Line 13

glPopMatrix();// Line 14

I

glColor3f(1.0,1.0,0.0); // Line 15

glTranslatef(-100.0,0.0,0.0); // Line 16

glScalef(0.5,1.0,1.0); // Line 17

I*S1*T2

glRecti(50,100,200,150); // Line 18

13:给定如下的代码行,请分析该程序执行后在显示窗口你将观察到的场景。

#include <gl/glut.h>

void display()

{

glClearColor(1.0,1.0,1.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(0.0,0.0,0.0);

glMatrixMode(GL_PROJECTION);

glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0); 

glMatrixMode(GL_MODELVIEW);

gluLookAt(0.0,0.0,0.0,0.0,0.0,-1.0,0.0,1.0,0); 

glutWireCube(0.5);//绘制边长为0.5的线框式立方体,且立方体的中心和世界坐标系原点重合

glFlush();

}

void main(int argc, char** argv)

{

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);

glutInitWindowSize(500,500);

glutInitWindowPosition(0,0);

glutCreateWindow("Orthogonal projection");

glutDisplayFunc(display);

glutMainLoop();

}

 答:显示边长为0.5的正方体的正投面:边长为0.5的正方形,背景色都是白色

14:给定如下的显示回调函数的代码片段,

glMatrixMode(GL_PROJECTION);//line 1

glLoadIdentity();//line 2

glOrtho(-1.0,1.0,-1.0,1.0,-1.0,999999.0);//line 3

glMatrixMode(GL_MODELVIEW);//line 4

glLoadIdentity();//line 5

gluLookAt(1.0,0.5,1.0,0.0,0.0,0.0,0.0,1.0,0); //line 6

glutWireCube(0.5);//line 7

glFlush();//line 8

如果将line 6代码用gluLookAt(10000.0,5000.0,10000.0,0.0,0.0,0.0,0.0,1.0,0);代替,那么代替前后在显示窗口上OpenGL绘制的立方体是否相同?原因是什么?

答:显示的立方体相同

因为在正交投影情况下,改变观察位置,但不改变观察方向和向上方向,对最终观察结

果没有影响。

15:给定如下四个显示回调函数的代码片段,试分析每个代码片段执行后绘制的立方体是否在正平行投影的可视化范围内? 

(1)显示回调函数代码片段1:

glOrtho(-1.0,1.0,-1.0,1.0,-1.0,2.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(1.0,0.5,1.0,0.0,0.0,0.0,0.0,1.0,0);

glutWireCube(0.5);

(2)显示回调函数代码片段2:

glOrtho(-1.0,1.0,-1.0,1.0,-1.0,999999.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(10000.0,5000.0,10000.0,0.0,0.0,0.0,0.0,1.0,0);

glutWireCube(0.5);

(3)显示回调函数代码片段3:

glOrtho(-1.0,1.0,-1.0,1.0,-1.0,2.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(10000.0,5000.0,10000.0,0.0,0.0,0.0,0.0,1.0,0);

glutWireCube(0.5);

4)显示函调函数代码片段4

glOrtho(-1.0,1.0,-1.0,1.0,-1.0,999999.0);//

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(1.0,0.5,1.0,0.0,0.0,0.0,0.0,1.0,0);

glutWireCube(0.5);

1)(2)(4)在  ;(3)不在;

16:给定如下的显示回调函数,试分析此时OpenGL定义的是点光源还是无穷远光源?如果是点光源,请分析该光源在世界坐标系中的位置。

void display(void)

{ 

GLfloat light0_pos[4] = {0.0, 0.0, 0.0, 1.0};

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);gluLookAt(4.0,4.0,4.0,0.0,0.0,0.0,0.0,1.0,0.0);

glutSolidTeapot(1.0);//glut object,自动计算每个顶点的法向量

glutSwapBuffers();

}

点光源(4.0,4.0,4.0

17:给定如下的显示回调函数,试分析此时OpenGL定义的是点光源还是无穷远光源?如果是点光源,请分析该光源在世界坐标系中的位置。

void display(void)

{

GLfloat light0_pos[4] = {0.0, 0.0, 0.0, 1.0};

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(4.0,4.0,4.0,0.0,0.0,0.0,0.0,1.0,0.0);

glLightfv(GL_LIGHT0, GL_POSITION, light0_pos); 

glutSolidTeapot(1.0); 

glutSwapBuffers();

}

点光源(0.0,0.0,0.0

18:给定如下的显示回调函数,请大致描述一下你将在显示窗口观察到的渲染场景。 

void display(void)

{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(4.0,4.0,4.0,0.0,0.0,0.0,0.0,1.0,0.0);

glPushMatrix();

glRotatef(theta,0.0,1.0,0.0);//theta表示一个随时间变化而变化的角度值

glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);

glPopMatrix();

glutSolidTeapot(1.0);

glutSwapBuffers();

}

茶壶可以由鼠标控制沿z轴旋转;光源和观察者绕着物体旋转,并且物体没有动(但看起来是物体在动,而光源和观察者没有动)。

19:在齐次坐标表示方法下,坐标位置的二维平移变换可以使用下面的矩阵乘法表示:

(1)

其中,分别表示方向和方向的平移量。

另外,坐标位置的二维绕原点旋转可以使用下面的矩阵乘法表示:

(2)

其中,表示旋转的角度。

给定二维空间的任意一点,请给出坐标位置绕点旋转角度的矩阵乘法表示公式。

     

            

20:在齐次坐标表示方法下,坐标位置的二维平移变换可以使用下面的矩阵乘法表示:

(1)

其中,分别表示方向和方向的平移量。

另外,坐标位置的二维相对于原点的缩放可以使用下面的矩阵乘法表示:

(2)

其中,分别表示在方向和方向的缩放系数。

给定二维空间的任意一点,请给出坐标位置相对于点且在方向和方向的缩放系数为的矩阵乘法表示公式。

      

21:说明OpenGL核心库、OpenGL实用库和OpenGL实用工具包之间的区别。

答: 

      Gl库是核心库,glu是实用库,glut是实用工具包

      Gl是核心,glu是对gl的部分封装,glutOpenGL的跨平台工具库。

      Gl中包含了最基本的3D函数,而glu似乎对gl的辅助

    glut是基本的窗口界面,是独立于glglu的,如果不喜欢用glut

       以用MFCWin32窗口等代替,但是glut是跨平台的,这就保证了我们编出的程序是

       跨平台的,如果用MFC或者Win32只能在windows操作系统上使用

选择OpenGL的一个很大原因就是因为它的跨平台性,所以我们可以尽量的使用glut

OpenGL核心库
核心库包含有115个函数,函数名的前缀为gl
这部分函数用于常规的、核心的图形处理。此函数由gl.dll来负责解释执行。由于许多函数可以接收不同数以下几类。据类型的参数,因此派生出来的函数原形多达300多个。
 OpenGL实用库

包含有43个函数,函数名的前缀为glu。
OpenGL提供了强大的但是为数不多的绘图命令,所有较复杂的绘图都必须从点。线、面开始。Glu 为了减轻繁重的编程工作,封装了OpenGL函数,Glu函数通过调用核心库的函数,为开发者提供相对简单的用法,实现一些较为复杂的操作。此函数由glu.dll来负责解释执行。OpenGL中的核心库和实用库可以在所有的OpenGL平台上运行。
OpenGL工具库 OpenGL Utility Toolkit
包含大约30多个函数,函数名前缀为glut。
glut是不依赖于窗口平台的OpenGL工具包,由Mark KLilgrad在SGI编写(现在在Nvidia),目的是隐藏不同窗口平台API的复杂度。 函数以glut开头,它们作为aux库功能更强的替代品,提供更为复杂的绘制功能,此函数由glut.dll来负责解释执行。由于glut中的窗口管理函数是不依赖于运行环境的,因此OpenGL中的工具库可以在X-Window, Windows NT, OS/2等系统下运行,特别适合于开发不需要复杂界面的OpenGL示例程序。对于有经验的程序员来说,一般先用glut理顺3D图形代码,然后再集成为完整的应用程序。
      

22:试分析三种画线算法:直线方程法、DDA方法、Bresenham方法的优劣。

解:直线方程法:只有整数运算,不含乘除法,可用硬件实现,但误差比较大

                 因(X0,Y0)在直线上,所以F(X0,Y0)=0

DDA算法:浮点数运算,不易硬件实现

Bresenham方法:不必计算机直线的斜率,因此不用做除法;

               不用浮点数,只用整数;

               只做整数加减法和乘2运算,而乘2运算可以用硬件移位实现

Bresenham算法速度很快,并适于用硬件实现

原创粉丝点击