计算机图形学实验报告.docx
- 文档编号:9041807
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:16
- 大小:168.97KB
计算机图形学实验报告.docx
《计算机图形学实验报告.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验报告.docx(16页珍藏版)》请在冰豆网上搜索。
计算机图形学实验报告
实验课程名称:
计算机图形学基础
实验项目名称
直线生成算法
实验成绩
实验者
专业班级
组别
同组者
实验日期
年月日
第一部分:
实验分析与设计(可加页)
一、实验内容描述(问题域描述)
通过本次实验掌握各种直线生成算法的基本原理和算法设计(包括Bresenham算法,中点画线法及DDA生成直线画法)。
二、实验基本原理与设计(包括实验方案设计,实验手段的确定,试验步骤等,用硬件逻辑或者算法描述)
DDA生成直线画法:
已知过端点的直线段L:
y=kx+b,直线斜率为
从x的左端点开始,向x右端点步进。
步长=1(象素个数),计算相应的y坐标y=kx+b;取象素点(x,round(y))作为当前点的坐标。
三、主要仪器设备及耗材
计算机VC++equippedwithOpenGL
第二部分:
实验调试与结果分析(可加页)
一、调试过程(包括调试方法描述、实验数据记录,实验现象记录,实验过程发现的问题等)
实验源代码:
#include"math.h"
#include
voidinit(void){
glClearColor(1.0,1.0,1.0,1.0);//设置窗口背景颜色
gluOrtho2D(0.0,50.0,0.0,50.0);//设置投影参数
}
voidset_pixel(floatx,floaty){//绘制一个点
glPointSize
(2);
glBegin(GL_POINTS);
glVertex2f(x,y);
glEnd();
}
voidlineWithDDA(GLintx0,GLinty0,GLintxn,GLintyn){//数值微分法
glColor3f(1.0,0.0,0.0);//设置当前的绘图颜色
GLfloatdx=xn-x0;
GLfloatdy=yn-y0;
GLintsteps=0;
GLfloatdeltaX=0;
GLfloatdeltaY=0;
GLfloatx=x0;
GLfloaty=y0;
if(abs(dx)>abs(dy))steps=abs(dx);
elsesteps=abs(dy);
steps*=10;//步长,可自行控制
deltaX=(GLfloat)dx/(GLfloat)steps;
deltaY=(GLfloat)dy/(GLfloat)steps;
for(GLfloati=0;i<=steps;i++){
set_pixel(x,y);
x+=deltaX;
y+=deltaY;
}
}
voiddisplay(){
glClear(GL_COLOR_BUFFER_BIT);//使用当前背景色填充窗口
lineWithDDA(9,9,30,40);
glFlush();//清空OpenGL命令缓冲区,执行OpenGL程序
}
voidmain(intargc,char**argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);//初始化窗口显示模式
glutInitWindowSize(250,250);//设置窗口的尺寸
glutInitWindowPosition(500,250);//设置窗口的位置
glutCreateWindow("OpenGL框架之直线与点");//设置窗口的名称
glutDisplayFunc(display);//设置当前窗口的显示回调函数
init();//完成窗口的初始化
glutMainLoop();//启动住GLUT时间处理循环
}
二、实验结果及分析(包括结果描述、实验现象分析、影响因素讨论、综合分析和结论等)
实验结果如下图:
三、实验小结、建议及体会
在这次实验中,学习了画线的方法(一个点一个点的画出),通过初始结点和末结点的坐标,来决策下一个结点的坐标。
对计算机中的画图方法有了进一层理解,对像素点也有了多一些的理解,希望以后可以更多的了解。
实验课程名称:
计算机图形学基础
实验项目名称
圆的生成算法
实验成绩
实验者
专业班级
组别
同组者
实验日期
年月日
第一部分:
实验分析与设计(可加页)
一、实验内容描述(问题域描述)
利用某种语言实现圆的生成(Bresenham算法)
二、实验基本原理与设计(包括实验方案设计,实验手段的确定,试验步骤等,用硬件逻辑或者算法描述)
圆的Bresenham算法思想:
设圆的半径为r,先考虑圆心在(0,0),并从x=0、y=r开始的顺时针方向的1/8圆周的生成过程。
在这种情况下,x每步增加1,从x=0开始,到x=y结束。
即有Xi+1=Xi+1,相应地yi+1则在两种可能中选择:
Yi+1=yi或者yi+1=yi-1
选择的原则是考虑精确值y是靠近yi还是靠近yi-1,计算公式为
Y2=r2-(xi+1)2
d1=yi2-y2=yi2-r2+(xi+1)2
d2=y2-(yi-1)2=r2-(xi+1)2-(yi-1)2
令pi=d1-d2,并代入d1、d2,则有
Pi=2(xi+1)2+yi2+(yi-1)2-2r2
(1)
Pi称为误差。
如果Pi<0,则yi+1=yi,否则yi+1=yi-1.pi的递归式为
Pi+1=pi+4xi+6+2(yi+12-yi2)-2(yi+1-yi)
(2)
Pi的初值由式
(1)代入xi=0,yi=r,而得
P1=3-2r(3)
根据上面的推导,圆周生成算法思想如下:
1.求误差初值,p1=3-2r,i=1,画点(0,r);
2.求下一个光栅位置,其中xi+1=xi+1,如果pi<0,则yi+1=yi,否则yi+1=yi-1;
3.画点(xi+1,yi+1);
4.计算下一个误差,如果pi<0,则pi+1=pi+4xi+6,否则pi+1=pi+4(xi-yi)+10;
5.I=i+1,如果x=y,则结束,否则返回步骤2;
实验源代码:
#include
#include"math.h"
#include
#defineR30//圆的半径
voidinit(void){
glClearColor(1.0,1.0,1.0,1.0);//设置窗口背景颜色
gluOrtho2D(0.0,200.0,0.0,150.0);//设置投影参数
}
voidset_pixel(intx,inty){//绘制一个点
glPointSize
(2);
glBegin(GL_POINTS);
glVertex2f(x,y);
glEnd();
}
voidCirclePoint(intx,inty){//八分画圆
glColor3f(1.0,0.0,0.0);//设置当前的绘图颜色
set_pixel(x+100,y+100);set_pixel(y+100,x+100);
set_pixel(-y+100,x+100);set_pixel(-x+100,y+100);
set_pixel(-x+100,-y+100);set_pixel(-y+100,-x+100);
set_pixel(y+100,-x+100);set_pixel(x+100,-y+100);
}
voidMidBresenham(intr){
intx,y,d;
//floatd;
x=0;
y=r;
d=1-r;
while(x<=y){
CirclePoint(x,y);
if(d<0)
d+=2*x+3;
else{
d+=2*(x-y)+5;
y--;
}
x++;
}
}
voiddisplay(void){
glClear(GL_COLOR_BUFFER_BIT);//使用当前背景色填充窗口
glColor3f(0.0,0.0,0.0);//设置当前的绘图颜色
MidBresenham(R);
glFlush();//清空OpenGL命令缓冲区,执行OpenGL程序
}
voidmain(intargc,char**argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);//初始化窗口显示模式
glutInitWindowSize(400,300);//设置窗口的尺寸
glutInitWindowPosition(100,120);//设置窗口的位置
glutCreateWindow("圆的生成");//设置窗口的名称
glutDisplayFunc(display);//设置当前窗口的显示回调函数
init();//完成窗口的初始化
glutMainLoop();//启动住GLUT时间处理循环
}
三、主要仪器设备及耗材
计算机VC++OpenGL
第二部分:
实验调试与结果分析(可加页)
一、实验结果如下:
二、实验小结、建议及体会
这次实验中,学习了对圆的画法,和第一个实验中画直线的方法类似,只是调用的方法有所不同,这样的学习过程是好的,一边学习一边实践,掌握的更熟练。
以后要多练习课上所学的知识。
实验课程名称:
计算机图形学基础
实验项目名称
橡皮筋技术实现直线和圆的生成
实验成绩
实验者
专业班级
组别
同组者
实验日期
年月日
第一部分:
实验分析与设计(可加页)
一、实验内容描述(问题域描述)
使用橡皮筋技术实现直线和圆的生成
二、实验基本原理与设计(包括实验方案设计,实验手段的确定,试验步骤等,用硬件逻辑或者算法描述)
实验代码:
1、橡皮筋技术之直线的生成
#include
intiPointNum=0;
intx1=0,x2=0,y1=0,y2=0;
intwinWidth=400,winHeight=300;
voidInitial(void){
glClearColor(1.0f,1.0f,1.0f,1.0f);
}
voidChangeSize(intw,inth){
winWidth=w;
winHeight=h;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,winWidth,0.0,winHeight);
}
voidDisplay(void){
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f,0.0f,0.0f);
if(iPointNum>=1){
glBegin(GL_LINES);
glVertex2i(x1,y1);
glVertex2i(x2,y2);
glEnd();
}
glutSwapBuffers();
}
voidMousePlot(GLintbutton,GLintaction,GLintxMouse,GLintyMouse){
if(button==GLUT_LEFT_BUTTON&&action==GLUT_DOWN){
if(iPointNum==0||iPointNum==2){
iPointNum=1;
x1=xMouse;
y1=winHeight-yMouse;
}
else{
iPointNum=2;
x2=xMouse;y2=winHeight-yMouse;
glutPostRedisplay();
}
}
if(button==GLUT_RIGHT_BUTTON&&action==GLUT_DOWN){
iPointNum=0;
glutPostRedisplay();
}
}
voidPassiveMouseMove(GLintxMouse,GLintyMouse){
if(iPointNum==1){
x2=xMouse;
y2=winHeight-yMouse;
glutPostRedisplay();
}
}
voidmain(intargc,char*argv[]){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowSize(400,300);
glutInitWindowPosition(100,100);
glutCreateWindow("橡皮筋技术");
glutDisplayFunc(Display);
glutReshapeFunc(ChangeSize);
glutMouseFunc(MousePlot);
glutPassiveMotionFunc(PassiveMouseMove);
Initial();
glutMainLoop();
}
2、橡皮筋之圆的生成
#include
#include"math.h"
intiPointNum=0;//已确定点的数目
intx_1=0,x2=0,y_1=0,y2=0;//确定的点坐标
intwinWidth=400,winHeight=300;//窗口的宽度和高度
voidInitial(void){
glClearColor(1.0f,1.0f,1.0f,1.0f);
}
voidChangeSize(intw,inth){
winWidth=w;winHeight=h;
glViewport(0,0,w,h);//指定窗口显示区域
glMatrixMode(GL_PROJECTION);//设置投影参数
glLoadIdentity();
gluOrtho2D(0.0,winWidth,0.0,winHeight);
}
voidset_pixel(floatx,floaty){//绘制一个点
glPointSize
(2);
glBegin(GL_POINTS);
glVertex2f(x,y);
glEnd();
}
voidCirclePoint(intx,inty){//八分画圆
glColor3f(1.0,0.0,0.0);//设置当前的绘图颜色
set_pixel(x+x_1,y+y_1);set_pixel(y+x_1,x+y_1);
set_pixel(-y+x_1,x+y_1);set_pixel(-x+x_1,y+y_1);
set_pixel(-x+x_1,-y+y_1);set_pixel(-y+x_1,-x+y_1);
set_pixel(y+x_1,-x+y_1);set_pixel(x+x_1,-y+y_1);
}
voidMidBresenham(intr){
intx,y,d;
//floatd;
x=0;
y=r;
d=1-r;
while(x<=y)
{
CirclePoint(x,y);
if(d<0)
d+=2*x+3;
else
{
d+=2*(x-y)+5;
y--;
}
x++;
}
}
voidDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f,0.0f,0.0f);
if(iPointNum>=1){
glBegin(GL_LINES);//绘制直线段
//glVertex2i(x1,y1);
//glVertex2i(x2,y2);
//lineWithDDA(x_1,y_1,x2,y2);//DDA画直线
doubled=(x2-x_1)*(x2-x_1)+(y2-y_1)*(y2-y_1);
MidBresenham(int(sqrt(d)));
glEnd();
}
glutSwapBuffers();//交换缓冲区
}
voidMousePlot(GLintbutton,GLintaction,GLintxMouse,GLintyMouse)
{
if(button==GLUT_LEFT_BUTTON&&action==GLUT_DOWN){
if(iPointNum==0||iPointNum==2){
iPointNum=1;
x_1=xMouse;y_1=winHeight-yMouse;//确定圆心
}
else{
iPointNum=2;
x2=xMouse;y2=winHeight-yMouse;//确定圆周上的点
glutPostRedisplay();//指定窗口重新绘制
}
}
if(button==GLUT_RIGHT_BUTTON&&action==GLUT_DOWN){
iPointNum=0;
glutPostRedisplay();
}
}
voidPassiveMouseMove(GLintxMouse,GLintyMouse)
{
if(iPointNum==1){
x2=xMouse;
y2=winHeight-yMouse;//确定圆周上的点
glutPostRedisplay();
}
}
intmain(intargc,char*argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);//使用双缓存及RGB模型
glutInitWindowSize(400,300);
glutInitWindowPosition(100,100);
glutCreateWindow("橡皮筋技术之直线生成");
glutDisplayFunc(Display);
glutReshapeFunc(ChangeSize);//指定窗口在整形回调函数
glutMouseFunc(MousePlot);//指定鼠标响应函数
glutPassiveMotionFunc(PassiveMouseMove);//指定鼠标移动响应函数
Initial();
glutMainLoop();
return0;
}
三、主要仪器设备及耗材
计算机VC++OpenGL
第二部分:
实验调试与结果分析(可加页)
一、实验结果及分析(包括结果描述、实验现象分析、影响因素讨论、综合分析和结论等)
橡皮筋之直线的生成:
橡皮筋技术之圆的生成:
二、实验小结、建议及体会
通过本次实验,我对OpenGL进行图形生成的操作有了更加升入的了解,学习了橡皮筋技术,同时也熟悉了OpenGL的鼠标响应的操作,发现编程其实挺有趣的,希望以后能继续在编程中的乐趣和培养、保持自己的兴趣。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机 图形学 实验 报告