计算机图形学基础教程实验报告Word文档格式.docx
《计算机图形学基础教程实验报告Word文档格式.docx》由会员分享,可在线阅读,更多相关《计算机图形学基础教程实验报告Word文档格式.docx(19页珍藏版)》请在冰豆网上搜索。
![计算机图形学基础教程实验报告Word文档格式.docx](https://file1.bdocx.com/fileroot1/2023-1/31/ac9dbc64-415f-4e45-84e7-267cf372c9e0/ac9dbc64-415f-4e45-84e7-267cf372c9e01.gif)
x<
=x1;
x++)
{
putpixel(x,y,color);
e+=2*dy;
if(e>
=0)
{y++;
e-=2*dx;
}
}
return0;
}
intmain()
initgraph(640,480);
bresenham(0,0,500,200,255);
while(!
kbhit())
closegraph();
Bresenham画圆法:
intcirclepoints(intx,inty,intcolor)
putpixel(255+x,255+y,color);
putpixel(255+y,255+x,color);
putpixel(255-x,255+y,color);
putpixel(255+y,255-x,color);
putpixel(255-x,255-y,color);
putpixel(255-y,255-x,color);
putpixel(255+x,255-y,color);
putpixel(255-y,255+x,color);
intbresenhamcircle(intr,intcolor)
intx,y,d;
x=0;
y=r;
d=3-2*r;
while(x<
=y)
circlepoints(x,y,color);
if(d<
0)
d+=4*x+6;
else
d=d+4*(x-y)+10;
y--;
x++;
bresenhamcircle(100,255);
五、实验结果记录与分析
实验结果如下:
6、疑难问题报告
2013年10月29日9、10节实验地点:
多边形的填充算法和曲线的绘制
1、实验目的
通过本次实验,熟练掌握种子填充算法和多边形扫描线填充算法以及bezier曲线或者B样条曲线的基本绘制算法,能够独立在vc环境下实现任意多边形的填充和一般曲线的绘制,进一步熟悉opengl的语法结构和强大的绘图功能,增强多媒体底层程序绘图能力。
1.选择种子填充算法或者多边形的扫描线算法完成多边形的填充。
2.选择bezier曲线或者B样条曲线算法完成曲线的绘制。
程序如下:
多边形扫描线填充算法:
//sweep.h
#ifndefSWEEP_H
#defineSWEEP_H
structEdge{
intnxty;
intcurx;
intdx,dy;
Edge*nxt;
};
voidsweep(intp[][2],intn,void(*setPixel)(int,int));
#endif
//sweepline.cpp
#include<
stdlib.h>
stdio.h>
glut.h>
#include"
sweep.h"
voidmyInit();
voidsetPixel(intx,inty);
voidmyDisplay();
intmain(intargc,char**argv){
glutInit(&
argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(640,480);
glutInitWindowPosition(100,150);
glutCreateWindow("
SweepLine"
);
glutDisplayFunc(&
myDisplay);
myInit();
glutMainLoop();
voidsetPixel(intx,inty){
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
voidmyInit(){
glClearColor(1.0,1.0,1.0,0.0);
glColor3f(0.0,0.0,0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,640.0,0.0,480.0);
voidmyDisplay(){
inti,j;
glClear(GL_COLOR_BUFFER_BIT);
intp[5][2];
p[0][0]=100;
p[0][1]=300;
p[1][0]=200;
p[1][1]=50;
p[2][0]=300;
p[2][1]=100;
p[3][0]=400;
p[3][1]=0;
p[4][0]=350;
p[4][1]=470;
sweep(p,5,setPixel);
glFlush();
}
//sweep.cpp
algorithm>
usingnamespacestd;
constintMAXN=1024;
intcp[MAXN][2],n;
inlineboolcmp(inti,intj){
returncp[i][1]<
cp[j][1]||(cp[i][1]==cp[j][1]&
&
cp[i][0]<
cp[j][0]);
Edge*e[MAXN],*h,*ph,*data;
voidinsert(intly,intpx,intind){
inty1,y2,y,nxt,pre,flag=0;
nxt=(ind+1)%n;
pre=(ind-1+n)%n;
y=cp[ind][1];
y1=cp[nxt][1];
y2=cp[pre][1];
if(y1>
y2)swap(y1,y2);
if(y1<
y&
y<
y2){
//需缩短一个单位
flag=1;
h=e[ly];
ph=NULL;
while(h){
if(h->
dy>
cp[ind][1]||(h->
dy==cp[ind][1]&
h->
dx>
cp[ind][0]))break;
ph=h;
h=h->
nxt;
}
data=newEdge;
data->
curx=px;
nxty=cp[ind][1];
dx=cp[ind][0]-px;
dy=cp[ind][1]-ly;
nxt=NULL;
if(flag)data->
nxty--;
if(ph){
nxt=ph->
ph->
nxt=data;
}else{
nxt=e[ly];
e[ly]=data;
intex[MAXN][MAXN],ne[MAXN];
inlineintabs(inta){
returna>
0?
a:
-a;
voidmakepoint(intline,Edge*h){
intdx=h->
dx,dy=h->
dy,t=0;
intx,y,flag=1;
if((h->
dx)*(h->
dy)<
0)flag=0;
for(y=line,x=h->
curx;
y<
=h->
nxty;
y++){
ex[y][ne[y]++]=x;
t+=2*abs(dx);
while(cnt>
=2*abs(dy)){
t-=2*abs(dy);
if(flag)x++;
elsex--;
voidsweep(intp[][2],intnn,void(*setPixel)(int,int)){
//对所有点按y坐标递增排序,y坐标相等的按x坐标递增排序
n=nn;
inti,j,k,ind,nxt,pre;
int*num=newint[n];
//点索引;
for(i=0;
i<
n;
i++)num[i]=i;
memcpy(cp,p,sizeof(cp));
sort(num,num+n,cmp);
//建立有序边表
memset(e,0,sizeof(e));
i++){
ind=num[i];
if(p[nxt][1]>
p[ind][1])insert(p[ind][1],p[ind][0],nxt);
if(p[pre][1]>
p[ind][1])insert(p[ind][1],p[ind][0],pre);
//处理activeedgelist
memset(ne,0,sizeof(ne));
MAXN;
h=e[i];
ph=NULL;
makepoint(i,h);
sort(ex[i],ex[i]+ne[i]);
for(j=0;
j<
ne[i];
j+=2)
for(k=ex[i][j];
k<
=ex[i][j+1];
k++)
setPixel(k,i);
Bezier曲线绘制:
GLfloatctrlpoints[4][3]={{-4.0,-4.0,0.0},{-2.0,4.0,0.0},{2.0,-4.0,0.0},{4.0,4.0,0.0}};
voidinit(void)
glClearColor(1.0,0.0,0.0,0.0);
glShadeModel(GL_FLAT);
glMap1f(GL_MAP1_VERTEX_3,0.0,1.0,3,4,&
ctrlpoints[0][0]);
glEnable(GL_MAP1_VERTEX_3);
voiddisplay(void)
inti;
glColor3f(1.0,1.0,0.0);
glBegin(GL_LINE_STRIP);
for(i=0;
i<
=30;
i++)
glEvalCoord1f((GLfloat)i/30.0);
glPointSize(5.0);
4;
glVertex3fv(&
ctrlpoints[i][0]);
voidreshape(intw,inth)
glViewport(0,0,(GLsizei)w,(GLsizei)h);
if(w<
=h)
glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w,5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0);
glOrtho(-5.0*(GLfloat)w/(GLfloat)h,5.0*(GLfloat)w/(GLfloat)h,-5.0,5.0,-5.0,5.0);
glMatrixMode(GL_MODELVIEW);
voidkeyboard(unsignedcharkey,intx,inty)
switch(key)
case27:
exit(0);
break;
intmain(intargc,char*argv[])
argc,argv);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
5、实验结果记录与分析
2013年11月26日9、10节实验地点:
简易交互式绘图系统的制作
运用前面所学的绘图知识,利用opengl基于MFC或者直接在MFC上调用函数构建一个简单的绘图系统,完成直线、圆、多边形、椭圆、bezier曲线等的绘制以及三维图形的简单运动与变幻以提高综合绘图能力和程序框架建构能力。
在vc环境中,利用opengl基于MFC或者直接在MFC上调用函数构建一个简单的绘图系统,完成直线、圆、多边形、椭圆、bezier曲线等的绘制以及三维图形的简单运动与变幻。
自定义菜单栏和工具栏,颜色可选,设计一个漂亮美观的绘图界面,并运行程序实现画图功能。
1.新建一个工程,选择MFCAppWizard[exe],并命名,确定后应用程序类型选择单文档,然后都点击下一步(默认的设置),完成后点击确定,一个基本的mfc程序框架就建立成功了。
2.在工作空间ResourceView中双击Menu,打开IDR_MAINFRAME,自定义或修改菜单选项,并给自定义的菜单选项取一个名字。
比如建立“绘图”菜单,在绘图菜单里面再建立“直线”、“多边形”“圆”等多个小菜单,如果菜单里面还要包含子菜单,就要将该菜单属性设置为“弹出”,最终子菜单不需要设置为“弹出”,但需要命一个名以便在程序中引用。
例如“直线”在“绘图”菜单里属于最终子菜单,可以命名为“ID_LINE”,相应的矩形命名为“ID_RECT”,圆命名为“ID_CIRCLE”等等。
3.自定义工具栏。
建立工具栏与自定义建立菜单类似,首先在工作空间ResourceView中双击Toolbar,可以直接在IDR_MAINFRAME上修改和增删工具,也可以新插入IDR_ToolBar。
在工具栏中,自己选择图案颜色绘制画图工具图标,并命以名字,以便在程序中引用,命名方式与自定义菜单栏完全相同。
并且工具栏和菜单栏的绘图功能可以相同。
4.将菜单栏、工具栏按钮与程序代码联系起来。
运用mfc最大的好处就是它能够简化应用程序,而这正是mfc强大的向导功能所作用的。
返回工作空间里的FileView,按快捷方式“ctrl+w”打开mfc向导,选中MessageMaps,选择view视图类,在ObjectIDs里面选择上两步建立的菜单栏和工具栏按钮的名字,在Message里面选择Command命令消息,点击AddFunction,则将相应的消息函数添加到视图类里面去了。
我们可以在view.h和view.cpp中找到相应函数的踪影。
比如,直线ID_LINE的消息函数就为OnLine(),矩形ID_RECT的消息函数就为OnRect()等等。
5.根据绘图功能,编写消息函数代码。
在FileView中打开SourceFile选中里边的视图类实现文件view.cpp,找到需要编写的消息函数。
例如,写画直线的消息函数就可以找到OnLine函数,修改其函数容为:
voidCMy2bView:
:
OnLine()
{Invalidate();
UpdateWindow();
CClientDCdc(this);
CPenpen;
pen.CreatePen(PS_SOLID,w,m_nColor);
dc.SelectObject(&
pen);
dc.MoveTo(500+rand()%20,100+rand()%20);
dc.LineTo(600+rand()%20,300+rand()%20);
//TODO:
Addyourcommandhandlercodehere
画矩形就找到OnRect函数,修改其函数容为:
OnRect()
Invalidate();
CBrushbrush;
brush.CreateSolidBrush(m_fColor);
brush);
dc.Rectangle(500+rand()%20,300+rand()%20,700+rand()%20,400+rand()%20);
画bezier曲线就找到OnBezier函数,修改其函数容为:
OnBezier()
POINTpoints[7];
points[0].x=300+rand()%50;
points[0].y=100+rand()%50;
points[1].x=400+rand()%50;
points[1].y=200+rand()%50;
points[2].x=500+rand()%50;
points[2].y=200+rand()%50;
points[3].x=600+rand()%50;
points[3].y=300+rand()%50;
points[4].x=700+rand()%50;
points[4].y=400+rand()%50;
points[5].x=500+rand()%50;
points[5].y=400+rand()%50;
points[6].x=400+rand()%50;
points[6].y=400+rand()%50;
dc.PolyBezier(points,7);
画一个椭圆的消息函数为:
OnEllipse()
dc.Ellipse(500+rand()%20,100+rand()%20,600+rand()%20,300+rand()%20);
Addyourcomma