计算机图形学实验报告
![计算机图形学实验报告](https://img.360docs.net/img94/1hbhw5dkc99a6tiqsfggsorslxn6mwp7-41.webp)
![计算机图形学实验报告](https://img.360docs.net/img94/1hbhw5dkc99a6tiqsfggsorslxn6mwp7-42.webp)
计算机图形学实验报告 This manuscript was revised on November 28, 2020
目录
实验一直线的DDA算法
一、【实验目的】
1.掌握DDA算法的基本原理。
2.掌握DDA直线扫描转换算法。
3.深入了解直线扫描转换的编程思想。
二、【实验内容】
1.利用DDA的算法原理,编程实现对直线的扫描转换。
2.加强对DDA算法的理解和掌握。
三、【测试数据及其结果】
四、【实验源代码】
#include<>
#include<>
#include
#include<>
GLsizei winWidth=500;
GLsizei winHeight=500;
void Initial(void)
{
glClearColor,,,;
glMatrixMode(GL_PROJECTION);
gluOrtho2D,,,;
}
void DDALine(int x0,int y0,int x1,int y1)
{
glColor3f,,;
int dx,dy,epsl,k;
float x,y,xIncre,yIncre;
dx=x1-x0; dy=y1-y0;
x=x0; y=y0;
if(abs(dx)>abs(dy)) epsl=abs(dx);
else epsl=abs(dy);
xIncre=(float)dx/(float)epsl;
yIncre=(float)dy/(float)epsl;
for(k=0;k<=epsl;k++)
{
glPointSize(3);
glBegin(GL_POINTS);
glVertex2i(int(x+,(int)(y+);
glEnd();
x+=xIncre;
y+=yIncre;
}
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
DDALine(100,100,200,180);
glFlush();
}
void winReshapeFcn(GLint newWidth, GLint newHeight)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D, GLdouble(newWidth), , GLdouble(newHeight)); glClear(GL_COLOR_BUFFER_BIT);
winWidth=newWidth;
winHeight=newHeight;
}
int main(int argc,char*argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(400,300);
glutInitWindowPosition(100,120);
glutCreateWindow("line");
Initial();
glutDisplayFunc(Display);
glutReshapeFunc(winReshapeFcn);
glutMainLoop();
return 0;
}
实验二 Bresenham绘制直线和圆
一、【实验目的】
1.掌握Bresenham算法扫描转换圆和直线的基本原理。
二、【实验内容】
1.利用Bresenham算法扫描转换圆和直线的基本原理编程实现对圆和直线的扫描转换。
三、【测试数据及其结果】
四、【实验源代码】
绘制直线:
#include<>
#include<>
#include
#include<>
GLsizei winWidth=500;
GLsizei winHeight=500;
void lineBres(int x0, int y0, int xEnd, int yEnd)
{
glColor3f, , ;
int dx=fabs(xEnd-x0), dy=fabs(yEnd-y0);
int p=2*dy-dx;
int twoDy=2*dy, twoDyMinusDx=2*(dy-dx);
int x, y;
if (x0>xEnd)
{
x=xEnd;
y=yEnd;
xEnd=x0;
}
else{
x=x0;
y=y0;
}
glPointSize(6);
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
while (x { x++; if (p<0) p+=twoDy; else{ y++; p+=twoDyMinusDx; } glPointSize(2); glBegin(GL_POINTS); glVertex2i(x, y); glEnd(); } } void init (void) { glClearColor, , , ; glShadeModel(GL_FLAT); } void display (void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); lineBres(10, 10, 400, 300); glFlush(); } void winReshapeFcn(GLint newWidth, GLint newHeight) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D, GLdouble(newWidth), , GLdouble(newHeight)); glClear(GL_COLOR_BUFFER_BIT); winWidth=newWidth; winHeight=newHeight; } void main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowPosition(10, 10); glutInitWindowSize(winWidth, winHeight); glutCreateWindow("lineBres"); init(); glutDisplayFunc(display); glutReshapeFunc(winReshapeFcn); glutMainLoop(); } 绘制圆: #include void init() { glClearColor(0,0,0,0); } void MidBresenhamCircle(int r) { int x,y,d; x=0; y=r; d=1-r; glBegin(GL_LINE_STRIP); while(x<=y){ glVertex2f(x,y); if(d<0) d+=2*x+3; else{ d+=2*(x-y)+5; y--; } x++; } glEnd(); } void display() { glClearColor(1,1,1,1); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1,0,0); MidBresenhamCircle(8); glRotated(45,0,0,1); MidBresenhamCircle(8); glRotated(45,0,0,1); MidBresenhamCircle(8); glRotated(45,0,0,1); MidBresenhamCircle(8); glRotated(45,0,0,1); MidBresenhamCircle(8); glRotated(45,0,0,1); MidBresenhamCircle(8); glRotated(45,0,0,1); MidBresenhamCircle(8); glRotated(45,0,0,1); MidBresenhamCircle(8); glutSwapBuffers(); } void reshape(int w,int h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-10,10,-10,10); } int main(int argc,char**argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); glutInitWindowSize(400,400); glutInitWindowPosition(100,100); glutCreateWindow("扫描转换圆"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMainLoop(); return 0; } 实验三反走样及五环的绘制 一、【实验目的】 1.了解走样和反走样的内容,熟练掌握用opengl实现图形的反走样。 2.学会用反走样消除走样现象。 3.学会五环的绘制方法。 二、【实验内容】 1.通过学习反走样相关课程,用opengl实现光栅图形的反走样。 2.绘制五环。 三、【测试数据及其结果】 四、【实验源代码】 反走样: #include #pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"") GLuint lineList; 1.0f1.0f1.0f0.0f1 2.0f4f2f1.0f1.0f2f4.0f2.0f2f2.0f5.0f3f3f3f3f3f3f练掌握各种裁剪算法和二维观察变换。 2.学会在屏幕坐标系下创建多个视区、指定视区的宽度和高度,了解二维观察变换中包含窗口到视区的映射。 二、【实验内容】 1.在一个显示窗口内指定多个视区,分别显示具有相同坐标、不同颜色和不同显示模式的各种图形面。 2.在书本给定程序基础上,对程序做一些改变并在视区中绘制各种图形。 三、【测试数据及其结果】 四、【实验源代码】 #include #include<> const float PI=; void initial(void) { glClearColor,,,; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D,,,; } void triangle(GLsizei mode) { if(mode==1) glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); else glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glBegin(GL_TRIANGLES); glVertex2f,; glVertex2f,; glVertex2f,; glEnd(); } void polygon(GLsizei mode) { if(mode==1) glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); else glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glBegin(GL_POLYGON); glVertex2f,; glVertex2f,; glVertex2f,; glVertex2f,; glVertex2f,; glEnd(); } void DrawCircle(GLfloat r) { GLfloat x,y,z; glBegin(GL_LINE_LOOP); for (int alpha=0;alpha<360;alpha++) { x=r*cos(alpha*PI/180); y=r*sin(alpha*PI/180); z=0; glVertex3f(x,y,z); } glEnd(); } void Display() { glClear(GL_COLOR_BUFFER_BIT); glColor3f,,; glViewport(0,0,100,100); triangle(1); glColor3f,,; glViewport(100,0,100,100); triangle(2); glColor3f,,; glViewport(0,100,100,100); polygon(2); glViewport(100,100,100,100); DrawCircle(5); glFlush(); } void main(void) { glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowPosition(10,10); glutInitWindowSize(400,200); glutCreateWindow("多视区"); initial(); glutDisplayFunc(Display); glutMainLoop(); } 实验五分子模型 一、【实验目的】 1.熟练掌握二维、三维几何变换矩阵和透视投影的相关知识从而用opengl实现分子模型的运动。 2.熟练掌握opengl中相关函数的调用和实现。 二、【实验内容】 1.显示分子模型:红色大球表示原子,三个黄色小球表示电子,分别绕原子旋转,采用透视投影变换显示电子旋转过程。 2.启用深度测试和模型视图矩阵完成分子动画。 三、【测试数据及其结果】 四、【实验源代码】 #include GLint angleSelf=0; void Initial() { glEnable(GL_DEPTH_TEST); glClearColor(1.0f,1.0f,1.0f,1.0f); } void ChangeSize(int w,int h) { if(h==0) h=1; glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); GLfloat fAspect; fAspect=(float)w/(float)h; gluPerspective,fAspect,1,; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void Display(void){ static float fElect1=0.0f; glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0f,0.0f,-250.0f); glColor3f(1.0f,0.0f,0.0f); glutWireSphere(12.0f,15,15); glColor3f(0.0f,1.0f,0.0f); glPushMatrix(); glRotatef(fElect1,0.0f,1.0f,0.0f); glTranslatef(90.0f,0.0f,0.0f); glRotatef(angleSelf,0,1,0); glutWireSphere(6.0f,15,15); glPopMatrix(); glPushMatrix(); glRotatef(45.0f,0.0f,0.0f,1.0f); glRotatef(fElect1,0.0f,1.0f,0.0f); glTranslatef(-70.0f,0.0f,0.0f); glRotatef(angleSelf,0,1,0); glutWireSphere(6.0f,15,15); glPopMatrix(); glPushMatrix(); glRotatef(-45.0f,0.0f,0.0f,1.0f); glRotatef(fElect1,0.0f,1.0f,; glTranslatef(0.0f,0.0f,60.0f); glRotatef(angleSelf,0,1,0); glutWireSphere(6.0f,15,15); glPopMatrix(); fElect1 +=5.0f; if(fElect1>360.0f) fElect1=10.0f; glutSwapBuffers(); } void RotateSelf(int value) { if(value==1) { angleSelf+=5; angleSelf%=360; glutPostRedisplay(); glutTimerFunc(100,RotateSelf,1); } } void TimerFunc(int value) { glutPostRedisplay(); glutTimerFunc(100,TimerFunc,1); } int main(int argc,char*argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH); glutCreateWindow("分子动画示例"); glutReshapeFunc(ChangeSize); glutDisplayFunc(Display); glutTimerFunc(500,TimerFunc,1); glutTimerFunc(100,RotateSelf,1); Initial(); glutMainLoop(); return 0; } 实验六 Bezier曲线 一、【实验目的】 1.掌握Bezire曲线定义。 2.掌握设计绘制一次、二次和三次Bezier曲线算法。 二、【实验内容】 1.绘制NURBS曲面。 2.基于Bezier定义根据控制多边形的阶次绘制Bezier曲线。 三、【测试数据及其结果】 四、【实验源代码】 原实验代码: #include #include<> #include<> class Pt3D{ public: GLfloat x,y,z; }; void GetCnk(GLint n,GLint *c) { GLint i,k; for(k=0;k<=n;k++){ c[k]=1; for(i=n;i>=k+1;i--)c[k]=c[k]*i; for(i=n-k;i>=2;i--)c[k]=c[k]/i; } } void GetPointPr(GLint *c,GLfloat t,Pt3D*Pt,int ControlN,Pt3D*ControlP) { GLint k,n=ControlN-1; GLfloat Bernstein; Pt->x=; Pt->y=; Pt->z=; for(k=0;k Bernstein=c[k]*pow(t,k)*pow(1-t,n-k); Pt->x+=ControlP[k].x*Bernstein; Pt->y+=ControlP[k].y*Bernstein; Pt->z+=ControlP[k].z*Bernstein; } } void BezierCurve(GLint m,GLint ControlN,Pt3D *ControlP) { GLint *C,i; Pt3D CurvePt; C=new GLint[ControlN]; GetCnk(ControlN-1,C); glBegin(GL_POINTS); for(i=0;i<=m;i++){ GetPointPr(C,(GLfloat)i/(GLfloat)m,&CurvePt,ControlN,ControlP); glVertex2f,; } glEnd(); delete [] C; } void initial(void) { glClearColor,,,; } void Display(void){ glClear(GL_COLOR_BUFFER_BIT); GLint ControlN=4,m=500; Pt3D ControlP[4]={{,,},{,,},{,,},{,,}}; glPointSize(2); glColor3f,,; BezierCurve(m,ControlN,ControlP); glBegin(GL_LINE_STRIP); for(GLint i=0;i<4;i++)glVertex3f(ControlP[i].x,ControlP[i].y,ControlP[i].z); glEnd(); glFlush(); } void reshape(GLint newWidth,GLint newHeight) { glViewport(0,0,newWidth,newHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D,,,; } void main(void) { glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowPosition(100,100); glutInitWindowSize(400,400); glutCreateWindow("Bezier曲线"); initial(); glutDisplayFunc(Display); glutReshapeFunc(reshape); glutMainLoop(); } 加改后的: #include void initial(void) { glClearColor,,,; glLineWidth; GLfloat ControlP[4][3]={{,,},{,,}, {,,},{,,}}; glMap1f(GL_MAP1_VERTEX_3,,,3,4,*ControlP); glEnable(GL_MAP1_VERTEX_3); } void Display(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f,,; glMapGrid1f(100,,; glEvalMesh1(GL_LINE,0,100); glFlush(); } void Reshape(GLint newWidth,GLint newHeight) { glViewport(0,0,newWidth,newHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D,,,; } void main(void) { glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowPosition(100,100); glutInitWindowSize(400,400);