计算机图形学常规上机题目

零、实验环境配置

image-20230129211142382

在计算机图形学课件中提供GLUT库,里面包含glut.hglut32.dllglut32.lib三个文件

image-20230129211313901

找到MinGW文件夹,将glut.h放进include/GL路径下,将glut32.dll放进bin路径下,将glut32.lib放在lib路径下,在代码中引用include <GL\glut.h>即可

如果使用的是vscode,需要在生成的配置文件task.json文件中修改

image-20230129211845176

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",并且放在前面,否则会报错。

image-20230130021718298

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连续性,并画出两条曲线段。

image-20230129211023543

image-20230129211028047

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

image-20230130133943825

给出直线的两个端点坐标$(x0,y0),(x1,y1)$,要求使用DDA算法绘制直线

加入断言,要求两点不能重合

首先计算dx和dy,对其绝对值进行比较,选其大者为自变量

不妨以x为自变量,如果遇到x0>x1的情况,需要将两点进行交换操作,以保证for循环能够正常工作

计算斜率k,进行增量操作

返回所得坐标点数量以及具体坐标,并绘画出来

题2

image-20230130133914711

算法思想是将判断中点与直线的位置关系,从而得到下一个像素点的坐标

这需要分成四种情况讨论,因为斜率与1的大小决定自变量,斜率的正负决定因变量的增减

题3image-20230130171140678

而对于第一个八分圆,初始$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

image-20230131105101639

题11

image-20230131105355843

image-20230131105406525

三、绘图代码部分

题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(); //告诉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);
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);//绕着向量(1,1,1)所指定的轴旋转45°
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);
// gluPerspective(60.0,aspectRatio,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();
//glTranslated(0.0,0.0,-200.0);//把整个场景移到到视图中
glLoadIdentity();
glRotatef(-num,1.0,1.0,1.0);//绕着向量(1,1,1)所指定的轴旋转45°
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);
// gluPerspective(60.0,aspectRatio,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();
// glClear(GL_COLOR_BUFFER_BIT);
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}}; // p1和p4端点
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}}; // p1到p4端点
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

image-20230130120605796

题2

image-20230130133436481

题3

image-20230130171055281

题4

image-20230130180455877

题5

image-20230130203058975

题6
image-20230130204619349 image-20230130204717657 image-20230130204733941 image-20230130204908854
题7
image-20230130214832971 image-20230130214758768
题8
image-20230130231544066 image-20230130231600838
题9

image-20230131102756999

题10

image-20230131104752802

题11

image-20230131105644787

五、实验小结

通过本次计算机图形学上机习题,我更加深刻的理解了光栅图形学算法,掌握了opengl画图方法,巩固了在课堂上的所学。