计算机图形学常规上机题目
零、实验环境配置
在计算机图形学课件中提供GLUT库,里面包含glut.h
、glut32.dll
、glut32.lib
三个文件
找到MinGW文件夹,将glut.h
放进include/GL
路径下,将glut32.dll
放进bin
路径下,将glut32.lib
放在lib
路径下,在代码中引用include <GL\glut.h>
即可
如果使用的是vscode,需要在生成的配置文件task.json
文件中修改
在args
参数栏中添加进”-l”, “glut32”, “-l”, “glu32”, “-l”, “opengl32”,
或者直接使用cmd编译,需要注意在后面加上-l glut32 -l glu32 -l opengl32
1
| gcc 1.cpp -o 1.exe -l glut32 -l glu32 -l opengl32
|
注意必须引入#include "windows.h"
,并且放在前面,否则会报错。
OpenGL入门代码分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| #include "windows.h" #include <GL/glut.h> void myinit(){ glClearColor(0.0,0.0,0.0,0.0); } void ChangeSize(GLsizei w,GLsizei h){ glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w<=h) glOrtho(-20.0,20.0,-20.0*(GLfloat)h/(GLfloat)w,20.0*(GLfloat)h/(GLfloat)w,-50.0,50.0); else glOrtho(-20.0*(GLfloat)h/(GLfloat)w,20.0*(GLfloat)h/(GLfloat)w,-20.0,20.0,-50.0,50.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void DrawMyObjects(){ glBegin(GL_POINTS); glColor3f(1.0,0.0,0.0); glVertex2f(-10.0,11.0); glColor3f(1.0,1.0,0.0); glVertex2f(-9.0,10.0); glColor3f(0.0,1.0,1.0); glVertex2f(-8.0,12.0); glEnd(); glBegin(GL_LINES); glColor3f(1.0,1.0,0.0); glVertex2f(-11.0,8.0); glVertex2f(-7.0,7.0); glColor3f(1.0,0.0,1.0); glVertex2f(-11.0,9.0); glVertex2f(-8.0,6.0); glEnd(); } void RenderScene(){ glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0,1.0,0.0); glPointSize(5); DrawMyObjects(); glFlush(); } int main(){ glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(500,500); glutInitWindowPosition(100,100); glutCreateWindow("Geometric Primitive Types"); myinit(); glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize); glutMainLoop(); return 0; }
|
glut初始化
void glutInitDisplayMode(unsigned int mode)
设置图形显示模式,参数mode值的含义为:
- GLUT_RGBA:当未指明GLUT-RGBA或GLUT-INDEX时,是默认使用的模式。表明欲建立RGBA模式的窗口
- GLUT_RGB:与GLUT-RGBA作用相同。
- GLUT_INDEX:指明为颜色索引模式。
- GLUT_SINGLE:只使用单缓存
- GLUT_DOUBLE:使用双缓存,避免把计算机作图的过程都表现出来,平滑地实现动画。
void glutInitWindowSize(int width,int height)
设置glut程序要产生的窗口的大小
void glutInitWindowPosition(int x,int y)
设置glut程序要产生的窗口的位置,以左上角为基准,以像素为单位
颜色管理
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
指定刷新颜色缓冲区时所用的颜色,指定值范围均为[0.0f, 1.0f ],(0.0, 0.0, 0.0, 0.0)底色设置为黑色。
void glClear(GLbitfield mask)
将缓存清除为预先的设置值,即将屏幕的所有像素点都还原为 “底色 ”,需要与glClearColor
搭配使用。
- GL_COLOR_BUFFER_BIT:指定当前被激活为写操作的颜色缓存
void glcolor3f(GLfloat red,GLfloat green,GLfloat blue)
用来设置画笔的颜色,即绘图颜色。属于RGBA模式。会根据表示颜色单位的不同或是否含alpha参量名称发生改变
glColor系列函数中,在参数类型不同时,表示“最大”颜色的值也不同。
采用 f 和 d 做后缀的函数,以 1.0 表示最大的使用。
采用 b 做后缀的函数,以 127 表示最大的使用。
采用 ub 做后缀的函数,以255 表示最大的使用。
采用 s 做后缀的函数,以 32767 表示最大的使用。
采用 us 做后缀的函数,以65535 表示最大的使用。
窗口管理
int glutCreateWindow(char* name)
产生一个顶层的窗口,name 作为窗口标题栏显示的内容。
返回值是生成窗口的标记符,可用函数glutGetWindow()
加以引用。
void glutDisplayFunc(void (*func)(void))
为当前窗口设置display回调函数
void glutReshapeFunc(void (*func)(int width, int height))
为当前窗口设置reshape回调函数
当窗口的尺寸发生变化时,或该窗口被另外一个窗口遮住时窗口应该发生重绘。设置回调函数可以让窗口变化后,窗口中的物体锁定纵横比,不产生变形
事件管理
void glutMainLoop(void)
让 glut 程序进入事件循环。在一个glut程序中最多只能调用一次。一旦调用,会直到程序结束才返回。
一、实验题目
第2章 光栅图形学算法上机作业
1.采用DDA算法在屏幕上画一条直线。
2.采用中点线算法在屏幕上画一条直线。
3.采用中点圆算法在屏幕上画一个圆。
第4章 图形几何变换上机作业
4.利用OpenGL实现一个立方体关于参考点(10.0,20.0,10.0)进行放缩变换,放缩因子为(2.0,1.0,0.5)。
5.利用OpenGL实现一个矩形关于y=x+5对称的新图形。
6.通过定义键盘回调函数,每按一次空格键,让三个点依次完成画点、画线、画三角形,并让三角形沿三角形中心旋转起来。
第5章 三维观察上机作业
7.编写程序,使一物体沿着一条直线匀速移动。
8.编写程序,使一物体围绕屏幕上一点匀速旋转。
注:物体可以是2D或3D(如果是3D图形,试着采用透视投影,观察近大远小的效果)
glutWireCube(GLdouble size);//线框立方体
glutWireTeapot(GLdouble size); //线框茶壶
第6章 曲线和曲面上机作业
9.证明如下的两条三次曲线段具有C1连续性,但没有G1连续性,并画出两条曲线段。
10.假定一条三次Hermite曲线的两个端点P1=<0,1>,P4=<3,0>,端点处切向量R1=<0,1>,R4=<-3,0>,请写出Hermite多项式形式,并绘出最后曲线,改变切向量,观察曲线形状变化。
11.绘制曲线:已知4点P1(0,0,0)、P2(1,1,1)、 P3(2,-1,-1)、P4(3,0,0),用其作为控制点分别绘制一条Bezier曲线、一条B样条曲线,并分别计算参数为0、1/3、 2/3、1时它们各自的位置矢量。
12.绘制曲面:利用Bezier曲面构造茶壶的表面形状,定义控制点:
$float ctrlpoints[4][4][3]$ = {
{ {-2, -1, 0}, { -2.0, -1.0, 4.0},
{ 2.0, -1.0, 4.0}, { 2, -1, 0} },
{ {-3, 0, 0}, { -3.0, 0, 6.0},
{ 3.0, 0, 6.0}, { 3, 0, 0}},
{ {-1.5, 0.5, 0}, {-1.5, 0.5, 3.0},
{1.5, 0.5, 3.0}, {1.5, 0.5, 0}},
{ {-2, 1, 0}, { -2.0, 1.0, 4.0},
{ 2.0, 1.0, 4.0}, { 2, 1, 0} }
};
第8章 真实感图形绘制
13.用不同的着色和光照参数绘制茶壶:
i.线框模型的茶壶
ii.没有光照的固定颜色的茶壶
iii.只有环境光,采用单一颜色的茶壶
iv.只有环境光和漫反射光,采用Gouraud插值着色的茶壶
v.有环境光、漫反射光和镜面高光,采用Gouraud插值着色的茶壶
选做题目:
14.将屏幕上的鼠标选取点进行连线,左键点击选中一个控制点(控制点数不超过64),按f键擦除第一个控制点,按l键擦除最后一个控制点,按Escape键退出。
15.将屏幕上的鼠标选取点作为多边形顶点进行填充。
16.模拟简单的太阳系,太阳在中心,地球每365天绕太阳转一周,月球每年绕地球转12周。另外,地球每天24个小时绕它自己的轴旋转。
二、算法描述
题1
给出直线的两个端点坐标$(x0,y0),(x1,y1)$,要求使用DDA算法绘制直线
加入断言,要求两点不能重合
首先计算dx和dy,对其绝对值进行比较,选其大者为自变量
不妨以x为自变量,如果遇到x0>x1的情况,需要将两点进行交换操作,以保证for循环能够正常工作
计算斜率k,进行增量操作
返回所得坐标点数量以及具体坐标,并绘画出来
题2
算法思想是将判断中点与直线的位置关系,从而得到下一个像素点的坐标
这需要分成四种情况讨论,因为斜率与1的大小决定自变量,斜率的正负决定因变量的增减
题3
而对于第一个八分圆,初始$4d_0=-8*r+5$
如果d<0,那么$4d=4d+8y+8$,画中点以右的点
如果d>0,那么$4d=4d-8x+8y+20$,画中点以左的点
题4
void glLoadIdentity(void)
该函数用一个4×4的单位矩阵替换当前矩阵,可以恢复初始坐标系。
void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
angle:为旋转的角度,单位为度。
x,y,z:为对应xyz轴的布尔值变量,代表旋转遵照的坐标轴,遵从右手原则。
void glTranslatef(GLfloat x,GLfloat y,GLfloat z)
函数功能:沿X,Y,Z轴正方向平移x,y,z个单位(为有符号数)
void glScalef(GLfloat x, GLfloat y, GLfloat z);
参数x,y,z分别为模型在x,y,z轴方向的缩放比。
void glPushMatrix(void)
与void glPushMatrix(void void)
将本次需要执行的缩放、平移等操作放在glPushMatrix和glPopMatrix之间,可以保存操作之前的状态,以便后续恢复
void glutWireCube(GLdouble)
用于绘制立方体
题5
void glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
画一个矩形,四个参数分别表示了位于对角线(左下到右上)上的两个点的横纵坐标(并且以窗口的中心点为原点,相当于以它为原点建立了一个二维坐标系)
通过定义矩形四个顶点坐标,并对其进行平移、旋转、对称、旋转、平移变换,最终得到关于直线对称的新图形
题6
void glutPostRedisplay(void)
通过glutMainLoop下一次循环时,窗口显示将被回调以重新显示窗口的正常面板。
void glutKeyboardFunc(void(*func)(unsigned char key,int x,int y))
func
: 处理普通按键消息的函数的名称。如果传递 NULL,则表示GLUT忽略普通按键消息。
这个作为glutKeyboardFunc
函数参数的函数需要有三个形参。第一个表示按下的键的ASCII码,其余两个提供了,当键按下时当前的鼠标位置。鼠标位置是相对于当前客户窗口的左上角而言的。
题7、题8
void glutTimerFunc(unsigned int msecs, void (*func)(int value), value)
如果用定时器的话,主函数初始时调用该函数,用于注册一个定时器的回调函数
该函数参数分别为:毫秒数, 回调函数指针,区别值
需要实现自己定义的回调函数,value用于区分定时器,可以在回调函数中定义一个随时间或位置改变的变量,用于实现动画效果。然后调用glutPostRedisplay()
重绘图像。在回调函数结尾再次调用glutTimerFunc()
,以实现循环计时。
题9
将函数定义域分成若干份,每一份根据该处X值得到函数值,将这些点连线从而画出曲线
证明:
$P1’=[2t-2,3t^2-4t+1],P2’=[2t,3t^2]$
所以$P1’|{t=1}=[0,0],P2’|{t=0}=[0,0]$
所以P1,P2有C1连续,因为[0,0]的方向不定,所以没有G1连续
题10
题11
三、绘图代码部分
题1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| #include "windows.h" #include "math.h" #include "assert.h" #include <GL\glut.h> typedef struct { int x,y; }point; void init(){ glClearColor(0.0f,0.0f,0.0f,1.0f); } void swap(int *a, int *b){ int x=*a; *a=*b; *b=x; } int LineDDA(int x0,int y0,int x1,int y1,point pixels[]){ int x,y; float k,xf,yf; assert(x0 != x1 || y0 != y1); int dx = x1-x0; int dy = y1-y0; int num = 0; if(fabs(dx) >= fabs(dy)){ if(dx<0){ swap(&x0, &x1); swap(&y0, &y1); } k = dy*1.0 / dx; yf = y0; for(int x=x0;x<=x1;x++){ pixels[num].x = x; pixels[num].y = int(yf+0.5); yf += k; num++; } } else{ if(dy<0){ swap(&x0, &x1); swap(&y0, &y1); } k = dx*1.0 / dy; xf = x0; for(int y=y0;y<=y1;y++){ pixels[num].x = int(xf+0.5); pixels[num].y = y; xf += k; num++; } } return num; } void drawLine(int x1,int y1,int x2,int y2){ point pixels[100]; int num; int i; num = LineDDA(x1,y1,x2,y2,pixels); glBegin(GL_POINTS); for(i=0;i<num;i++) glVertex2i(pixels[i].x,pixels[i].y); glEnd(); } void RenderScene() { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0f,0.0f,0.f); glPointSize(1); drawLine(50,30,-40,-70); 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(-100.0,100.0,-100.0/aspectRatio,100.0/aspectRatio,1.0,-1.0); else glOrtho(-100.0*aspectRatio,100.0*aspectRatio,-100.0,100.0,1.0,-1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(){ glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE); glutCreateWindow("LineDDA"); init(); glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize); glutMainLoop(); return 0; }
|
题2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| #include "windows.h" #include "math.h" #include "assert.h" #include <GL\glut.h> typedef struct { int x,y; }point; void init(){ glClearColor(0.0f,0.0f,0.0f,1.0f); } void swap(int *a, int *b){ int x=*a; *a=*b; *b=x; } int MidPoint(int x0,int y0,int x1,int y1,point pixels[]){ assert(x0 != x1 || y0 != y1); int a = y0-y1; int b = x1-x0; int num = 0; if(fabs(a) < fabs(b)){ if(b<0){ swap(&x0, &x1); swap(&y0, &y1); a = -a; b = -b; } int yf = y0; pixels[num].x = x0; pixels[num].y = yf; num++; int d = 2*a+b; int d1 = 2*a; int d2 = 2*a+b; for(int x=x0+1;x<=x1;x++){ if(d > 0){ yf = a>0?yf-1:yf; pixels[num].x = x; pixels[num].y = yf; d += d1; num++; } else{ yf = a>0?yf:yf+1; pixels[num].x = x; pixels[num].y = yf; d += d2; num++; } } } else{ if(a>0){ swap(&x0, &x1); swap(&y0, &y1); a = -a; b = -b; } int xf = x0; pixels[num].x = xf; pixels[num].y = y0; num++; int d = 2*b+a; int d1 = 2*b; int d2 = 2*b+a; for(int y=y0+1;y<=y1;y++){ if(d <= 0){ xf = b<0?xf-1:xf; pixels[num].x = xf; pixels[num].y = y; d += d1; num++; } else{ xf = b<0?xf:xf+1; pixels[num].x = xf; pixels[num].y = y; d += d2; num++; } } } return num; } void drawLine(int x1,int y1,int x2,int y2){ point pixels[100]; int num; int i; num = MidPoint(x1,y1,x2,y2,pixels); glBegin(GL_POINTS); for(i=0;i<num;i++) glVertex2i(pixels[i].x,pixels[i].y); glEnd(); } void RenderScene() { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0f,0.0f,0.f); glPointSize(1); drawLine(40,-30,-40,30); 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(-100.0,100.0,-100.0/aspectRatio,100.0/aspectRatio,1.0,-1.0); else glOrtho(-100.0*aspectRatio,100.0*aspectRatio,-100.0,100.0,1.0,-1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(){ glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE); glutCreateWindow("MidPoint"); init(); glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize); glutMainLoop(); return 0; }
|
题3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| #include "windows.h" #include <GL\glut.h> typedef struct { int x,y; }point; void init(){ glClearColor(0.0f,0.0f,0.0f,1.0f); } int MidPoint(int r, point pixels[]){ int x = r; int y = 0; int d = -8*r+5; int num = 0; pixels[num].x = x; pixels[num].y = y; num++; x--; y--; while(x>y){ if(d<0){ d+=8*y+8; } else{ d+=-8*x+8*y+20; x--; } pixels[num].x = x; pixels[num].y = y; num++; y++; } return num; } void drawCircle(int r){ point pixels[100]; int num; int i; num = MidPoint(r, pixels); glBegin(GL_POINTS); for(i=0;i<num;i++){ glVertex2i(pixels[i].x, pixels[i].y); glVertex2i(-1*pixels[i].x, pixels[i].y); glVertex2i(pixels[i].x, -1*pixels[i].y); glVertex2i(-1*pixels[i].x, -1*pixels[i].y); glVertex2i(pixels[i].y, pixels[i].x); glVertex2i(-1*pixels[i].y, pixels[i].x); glVertex2i(pixels[i].y, -1*pixels[i].x); glVertex2i(-1*pixels[i].y, -1*pixels[i].x); } glEnd(); } void RenderScene() { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0f,0.0f,0.f); glPointSize(1); drawCircle(30); 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(-100.0,100.0,-100.0/aspectRatio,100.0/aspectRatio,1.0,-1.0); else glOrtho(-100.0*aspectRatio,100.0*aspectRatio,-100.0,100.0,1.0,-1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(){ glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE); glutCreateWindow("LineDDA"); init(); glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize); glutMainLoop(); return 0; }
|
题4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #include "windows.h" #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); glPushMatrix(); glutWireCube(10.0); glColor3f(0.0,0.0,1.0); glLoadIdentity(); glTranslatef(10.0,20.0,10.0); glRotatef(45.0,1.0,1.0,1.0); glScalef(2.0,1.0,0.5); glTranslatef(-10.0,-20.0,-10.0); 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(){ glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE); glutCreateWindow("Cube"); init(); glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize); glutMainLoop(); return 0; }
|
题5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| #include "windows.h" #include <GL\glut.h> #include <math.h> const double pi=3.1415926; void init(){ glClearColor(1.0,1.0,1.0,1.0); } float point[4][2] = {-20.0,5.0,-10.0,5.0,-10.0,25.0,-20.0,25.0}; void translate(int x, int y, float point[4][2]){ for(int i=0;i<4;i++){ point[i][0] += x; point[i][1] += y; } } void rotate(int angle, float point[4][2]){ for(int i=0;i<4;i++){ int oldx = point[i][0]; int oldy = point[i][1]; point[i][0] = oldx*cos(angle * pi / 180)-oldy*sin(angle * pi / 180); point[i][1] = oldx*sin(angle * pi / 180)+oldy*cos(angle * pi / 180); } } void rectangle(){ glBegin(GL_LINE_LOOP); glVertex2f(point[0][0], point[0][1]); glVertex2f(point[1][0], point[1][1]); glVertex2f(point[2][0], point[2][1]); glVertex2f(point[3][0], point[3][1]); glEnd(); } void symmetry(int x, int y, float point[2][2]){ for(int i=0;i<4;i++){ point[i][0] *= x; point[i][1] *= y; } } void RenderScene(){ glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0,1.0,1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glBegin(GL_LINES); glColor3f(1.0,1.0,0.0); glVertex2f(-50.0, 0.0); glVertex2f(50.0, 0.0); glEnd(); glBegin(GL_LINES); glColor3f(1.0,1.0,0.0); glVertex2f(0.0, -50.0); glVertex2f(0.0, 50.0); glEnd(); glBegin(GL_LINES); glColor3f(1.0,1.0,0.0); glVertex2f(-50.0, -45.0); glVertex2f(50.0, 55.0); glEnd(); glColor3f(1.0,0.0,0.0); rectangle(); translate(0, -5, point); rotate(-45, point); symmetry(1, -1, point); rotate(45, point); translate(0, 5, point); glColor3f(0.0,1.0,0.5); rectangle(); 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(){ glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE); glutCreateWindow("Cube"); init(); glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize); glutMainLoop(); return 0; }
|
题6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| #include"windows.h" #include <stdlib.h> #include <stdio.h> #include <GL/glut.h> int currentMode = 0; const int ModeNums = 4; void init(){ glClearColor(1.0,1.0,1.0,1.0); } void myKey(unsigned char key, int x, int y){ switch(key){ case ' ': currentMode = (currentMode+1)%ModeNums; glutPostRedisplay(); 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); break; case 1: glBegin(GL_LINE_LOOP); glColor3f(0.0,0.0,1.0); break; case 2: glBegin(GL_TRIANGLES); glColor3f(1.0,1.0,0.0); break; case 3: glTranslatef(5.5,5.0,0.0); glRotatef(45.0,0.0,0.0,1.0); glTranslatef(-5.5,-5.0,0.0); break; } glVertex2f( 3.0, 3.0 ); glVertex2f( 8.0, 3.0 ); glVertex2f( 5.0, 8.0 ); glEnd(); 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(){ glutInitDisplayMode(GLUT_SINGLE|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; }
|
题7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| #include "windows.h" #include <GL\glut.h> int num; 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(); glTranslated(0.0,0.0,-200.0); glBegin(GL_LINES); glColor3f(0.0,1.0,0.0); glVertex3f(-200.0, -200.0, -200.0); glVertex3f(200.0, 200.0, 200.0); glEnd(); glLoadIdentity(); glRotatef(90.0,1.0,1.0,1.0); glTranslated(-200,-200,-200); glTranslated(num,num,num); glColor3f(1.0,0.0,0.0); glutWireCube(100.0); glFlush(); } void myTimer(int value){
num++; glutPostRedisplay(); glutTimerFunc(100,myTimer,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(-200.0,200.0,-200.0/aspectRatio,200.0/aspectRatio,10.0,400.0); else glOrtho(-200.0*aspectRatio,200.0*aspectRatio,-200.0,200.0,10.0,400.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(){ num = 0; glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE); glutCreateWindow("Cube"); init(); glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize); glutTimerFunc(100, myTimer, 1); glutMainLoop(); return 0; }
|
题8
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| #include "windows.h" #include <GL\glut.h> int num; 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(); glLoadIdentity(); glRotatef(-num,1.0,1.0,1.0); glColor3f(1.0,0.0,0.0); glutWireCube(100.0); glFlush(); } void myTimer(int value){
num++; glutPostRedisplay(); glutTimerFunc(20,myTimer,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(-200.0,200.0,-200.0/aspectRatio,200.0/aspectRatio,10.0,400.0); else glOrtho(-200.0*aspectRatio,200.0*aspectRatio,-200.0,200.0,10.0,400.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(){ num = 0; glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE); glutCreateWindow("Cube"); init(); glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize); glutTimerFunc(100, myTimer, 1); glutMainLoop(); return 0; }
|
题9
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| #include "windows.h" #include<GL/glut.h> typedef struct{ float x,y,z; }Point; void init(){ glClearColor(1.0,1.0,1.0,1.0); } void DrawCurve(int n){ Point p,q; double t,deltat; int i; deltat = 1.0/(n-1); glBegin(GL_LINE_STRIP); for(i=0;i<100;i++){ t = deltat*i; p.x = t*t-2*t+1; p.y = t*t*t-2*t*t+t; p.z = 0; glVertex3f(p.x,p.y,p.z); } glEnd(); glColor3f(0,1,0); glBegin(GL_LINE_STRIP); for(i=0;i<100;i++){ t=i*deltat; q.x=t*t; q.y=t*t*t; q.z=0; glVertex3f(q.x,q.y,q.z); } glEnd(); } void RenderScence(){ glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0,0.0,0.0); DrawCurve(100); 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; float s=2; if(w<=h) glOrtho(-s,s,-s/aspectRatio,s/aspectRatio,1.0,-1.0); else glOrtho(-s*aspectRatio,s*aspectRatio,-s,s,1.0,-1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(){ glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutCreateWindow("DrawBezier"); init(); glutDisplayFunc(RenderScence); glutReshapeFunc(ChangeSize); glutMainLoop(); return 0; }
|
题10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| #include "windows.h" #include <GL/glut.h> #include <string> typedef struct{ float x, y; } Point; void init(){ glClearColor(1.0, 1.0, 1.0, 1.0); } void DrawHermite2D(int n, Point P[], Point R[]){ Point p; double t, deltat, t2, t3; int i; deltat = 1.0 / (n - 1); glBegin(GL_LINE_STRIP); for (i = 0; i < 100; i++){ t = i * deltat; t2 = t * t; t3 = t * t2; double BH1 = 2 * t3 - 3 * t2 + 1; double BH2 = -2 * t3 + 3 * t2; double BH3 = t3 - 2 * t2 + t; double BH4 = t3 - t2; p.x = P[0].x * BH1 + P[1].x * BH2 + R[0].x * BH3 + R[1].x * BH4; p.y = P[0].y * BH1 + P[1].y * BH2 + R[0].y * BH3 + R[1].y * BH4; glVertex2f(p.x, p.y); } glEnd(); glColor3f(0, 1, 0); glPointSize(3); glBegin(GL_POINTS); for (i = 0; i < 2; i++){ glVertex2d(P[i].x, P[i].y); glVertex2d(P[i].x + R[i].x, P[i].y + R[i].y); } glEnd(); } void RenderScence(){ glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0); Point P[2] = {{0, 1}, {3, 0}}; Point R[2] = {{0, 1}, {-3, 0}}; DrawHermite2D(100, P, R); 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; float s = 8; if (w <= h) glOrtho(-s, s, -s / aspectRatio, s / aspectRatio, 1.0, -1.0); else glOrtho(-s * aspectRatio, s * aspectRatio, -s, s, 1.0, -1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(){ glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutCreateWindow("DrawBezier"); init(); glutDisplayFunc(RenderScence); glutReshapeFunc(ChangeSize); glutMainLoop(); return 0; }
|
题11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| #include "windows.h" #include <GL\glut.h> #include <string> typedef struct{ float x, y, z; } Point; void init(){ glClearColor(1.0, 1.0, 1.0, 1.0); } void DrawBezier3D(int n, Point P[]){ Point p; double t, deltat, t2, t3, et, et2, et3; int i; deltat = 1.0 / (n - 1); glBegin(GL_LINE_STRIP); for (i = 0; i < 100; i++){ t = i * deltat; et = 1 - t; t2 = t * t; et2 = et * et; t3 = t * t2; et3 = et * et2; p.x = et3 * P[0].x + 3 * t * et2 * P[1].x + 3 * t2 * et * P[2].x + t3 * P[3].x; p.y = et3 * P[0].y + 3 * t * et2 * P[1].y + 3 * t2 * et * P[2].y + t3 * P[3].y; p.z = et3 * P[0].z + 3 * t * et2 * P[1].z + 3 * t2 * et * P[2].z + t3 * P[3].z; glVertex3f(p.x, p.y, p.z); } glEnd(); glColor3f(0, 1, 0); glPointSize(3); glBegin(GL_POINTS); for (i = 0; i < 4; i++){ glVertex2d(P[i].x, P[i].y); } glEnd(); } void DrawB3D(int n, Point P[]){ Point p; double t, deltat, t2, t3, et, et2, et3; int i; deltat = 1.0 / (n - 1); glBegin(GL_LINE_STRIP); for (i = 0; i < 100; i++){ t = i * deltat; et = 1 - t; t2 = t * t; et2 = et * et; t3 = t * t2; et3 = et * et2; p.x = et3 * P[0].x / 6 + (3 * t3 - 6 * t2 + 4) * P[1].x / 6 + (-3 * t3 + 3 * t2 + 3 * t + 1) * P[2].x / 6 + t3 * P[3].x / 6; p.y = et3 * P[0].y / 6 + (3 * t3 - 6 * t2 + 4) * P[1].y / 6 + (-3 * t3 + 3 * t2 + 3 * t + 1) * P[2].y / 6 + t3 * P[3].x / 6; p.z = et3 * P[0].z / 6 + (3 * t3 - 6 * t2 + 4) * P[1].z / 6 + (-3 * t3 + 3 * t2 + 3 * t + 1) * P[2].z / 6 + t3 * P[3].z / 6; glVertex3f(p.x, p.y, p.z); } glEnd(); glColor3f(0, 1, 0); glPointSize(3); glBegin(GL_POINTS); for (i = 0; i < 4; i++){ glVertex2d(P[i].x, P[i].y); } glEnd(); } void RenderScence(){ glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0); Point P[4] = {{0, 0, 0}, {1, 1, 1}, {2, -1, -1}, {3, 0, 0}}; DrawBezier3D(100, P); DrawB3D(100, P); 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; float s = 5; if (w <= h) glOrtho(-s, s, -s / aspectRatio, s / aspectRatio, 1.0, -1.0); else glOrtho(-s * aspectRatio, s * aspectRatio, -s, s, 1.0, -1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(){ glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutCreateWindow("Draw_Bezier/B"); init(); glutDisplayFunc(RenderScence); glutReshapeFunc(ChangeSize); glutMainLoop(); return 0; }
|
四、实验结果截图
题1
题2
题3
题4
题5
题6
题7
题8
题9
题10
题11
五、实验小结
通过本次计算机图形学上机习题,我更加深刻的理解了光栅图形学算法,掌握了opengl画图方法,巩固了在课堂上的所学。