图形学实验指导书.docx
- 文档编号:11765950
- 上传时间:2023-04-01
- 格式:DOCX
- 页数:28
- 大小:131.95KB
图形学实验指导书.docx
《图形学实验指导书.docx》由会员分享,可在线阅读,更多相关《图形学实验指导书.docx(28页珍藏版)》请在冰豆网上搜索。
图形学实验指导书
实验一DDA画线算法
一、实验学时:
2
二、实验类型:
验证性实验
三、实验要求和目的
初步了解Tc下画图基本程序结构。
初步了解DDA画线算法的思想和基本方法。
四、实验内容
DDA画线算法画一段直线
1.算法思路
1.算法描述:
设直线方程为:
,
对于直线,其数值微分是
由上式得,y(i+1)=y(i)+m(x(i+1)-x(i)),于是知,使x(i)增1,即x(i+1)=x(i)+1时,y(i+1)=y(i)+m,为画线精确,应使相邻的画出点的坐标值相差最大值为1,这样可以得到画线段的数值微分分析器(DigitalDifferentialAnalyzer,简称DDA),算法如下:
2.C程序代码
#include
#include
#include
voidDDALine(intx1,inty1,intx2,inty2,intcolor)
{
doubledx,dy,e,x,y,i;
dx=x2-x1;
dy=y2-y1;
e=(fabs(dx)>fabs(dy))?
fabs(dx):
fabs(dy);
dx/=e;
dy/=e;
x=x1;
y=y1;
for(i=1;i<=e;i++)
{putpixel((int)(x+0.5),(int)(y+0.5),color);
x+=dx;
y+=dy;
}
}
voidmain()
{intdriver=DETECT;
intgmode;
intx1,y1,x2,y2,color;
printf("pleaseinputx1,y1,y1,y2,color\n");
scanf("%d,%d,%d,%d,%d",&x1,&y1,&x2,&y2,&color);
initgraph(&driver,&gmode,"");
DDALine(x1,y1,x2,y2,color);
getch();
closegraph();
}
实验二Bresenham画线算法
一、实验学时:
2
二、实验类型:
验证性实验
三、实验要求和目的
掌握中点画线算法的思想和基本方法
四、实验内容
用Bresenham画线算法画直线,并完善算法功能,使之适应更广
1.算法思路
假定直线段的斜率0≤m≤1,且x2>x1,
若差为正,即
,下一个象素应取
;若为负,即
,下一个象素应取
。
引入新的判别量pi
其中
,又因为
,所以有
应取
,此时
pi<0,应取
此时
初始值的确定:
2.C程序代码
#include
#include
#include
voidBresenhamLine(intx1,inty1,intx2,inty2,intcolor)
{
intx,y,dx,dy,p;
x=x1;
y=y1;
dx=x2-x1;
dy=y2-y1;
p=2*dy-dx;
for(x=1;x<=x2;x++)
{
putpixel(x,y,color);
if(p>=0)
{y++;
p+=2*(dy-dx);
}
else
{p+=2*dy;
}
}
}
voidmain()
{intdriver=DETECT;
intgmode;
intx1,y1,x2,y2,color;
printf("pleaseinputx1,y1,x2,y2,color");
scanf("%d,%d,%d,%d,%d",&x1,&y1,&x2,&y2,&color);
initgraph(&driver,&gmode,"");
BresenhamLine(x1,y1,x2,y2,color);
getch();
closegraph();
}
实验三中点画圆算法
一、实验学时:
2
二、实验类型:
验证性实验
三、实验要求和目的
掌握中点画圆算法的基本思想
编写中点画圆的基本函数并尽量完善
四、实验内容
中点画圆算法画圆
1.算法描述:
构造函数
对于圆上的点,有F(x,y)=0;对于圆外的点,有F(x,y)>0;对于圆内的点,有F(x,y)<0。
设M的坐标为:
M(xi+1,yi-0.5),构造判别式:
,
当d<0时,下一点取P1;
当d>=0时,下一点取P2。
当d<0时,下一点取P1,再下一个点的判别式:
当d>=0时,下一点取P2,再下一个点的判别式:
判别式的初值:
2.源程序:
#include
#include
#include
voidMidpointCircle(intx0,inty0,intR)
{
intx,y;
doubled;
x=0;
y=R;
d=1.25-R;
while(x {if(d<0) {d+=x+x+3; x++;} else {d+=(x-y)+(x-y)+5; x++; y--;} putpixel(x0+x,y0+y,RED); putpixel(x0+y,y0+x,RED); putpixel(x0+y,y0-x,RED); putpixel(x0+x,y0-y,RED); putpixel(x0-x,y0-y,RED); putpixel(x0-y,y0-x,RED); putpixel(x0-y,y0+x,RED); putpixel(x0-x,y0+y,RED); } } main() {intdriver=DETECT,mode; initgraph(&driver,&mode,""); MidpointCircle(200,200,100); getch(); closegraph(); } 1. 实验四Bresenham画圆算法 一、实验学时: 2 二、实验类型: 验证性实验 三、实验要求和目的 掌握Bresenham画圆算法的基本思想 编写Bresenham算法画圆的基本函数并尽量完善 四、实验内容 Bresenham画圆算法画圆,并改造函数,使之能画整圆。 1.算法思路 先求(0,R)到 之间的四分之一圆弧,然后由对称性求得整个圆。 取 ,圆周上y的变化小于1,若第i步是 ,那么第i+1步只能是H(Xi+1,Yi)和D(Xi+1,Yi+1)点中的一个,H和D点离圆心距离的平方差 令判别量 当Pi<0时,下一点应选H点, 。 当Pi>=0时,下一点应选D点。 。 2.源程序: #include #include #include voidBresenhamCirle(intR) { intx,y,p; x=0; y=R; p=3-2*R; for(;x<=y;x++) {putpixel(x+200,y+100,3); putpixel(x+200,-y+100,3); putpixel(y+200,x+100,3); putpixel(-y+200,x+100,3); putpixel(-x+200,y+100,3); putpixel(-x+200,-y+100,3); putpixel(-y+200,x+100,3); putpixel(-y+200,-x+100,3); if(p>=0) { p+=4*(x-y)+10; y--; } else { p+=4*x+6; } } } voidmain() {intdriver=DETECT,gmode; initgraph(&driver,&gmode,""); BresenhamCirle(150); getch(); closegraph(); } 实验五正方形旋转 一、实验学时: 2 二、实验类型: 验证性实验 三、实验要求和目的 掌握图形的旋转变换数学原理 掌握一般图形旋转的基本算法 四、实验内容 画一个正方形,并实现45度旋转,进一步可以使之动起来. 1算法思路 旋转变换: 式中, 是图形以坐标原点为旋转中心的旋转角度。 本程序实现相对于任意一点(x0,y0)作变换,可以先平移到原点,相对于原点作变换后,再平移回去。 相对于任意一点(x0,y0)的旋转变换矩阵如下: T(-x0,-y0)R( ).T(x0,y0) = 1.= 2.C程序代码 #include #include voidmain() { inti,j,s,k; floatcx; float a[4][3]={{400,200,1},{300,200,1},{300,300,1},{400,300,1}}; floatpingyi[3][3]={{1,0,0},{0,1,0},{-125,-125,1}}; floatrpingyi[3][3]={{1,0,0},{0,1,0},{125,125,1}}; floatzhuan[3][3]={{0,0,0},{0,0,0},{0,0,1}}; floataxb[4][3]; floatzaxb[4][3]; floatrp[4][3]; intgdriver=DETECT,gmade; initgraph(&gdriver,&gmade,""); line(a[0][0],a[0][1],a[1][0],a[1][1]); line(a[1][0],a[1][1],a[2][0],a[2][1]); line(a[2][0],a[2][1],a[3][0],a[3][1]); line(a[3][0],a[3][1],a[0][0],a[0][1]); for(i=0;i<4;i++) { for(j=0;j<3;j++) { s=0; for(k=0;k<3;k++) { s=s+a[i][k]*pingyi[k][j]; } axb[i][j]=s; } } line(axb[0][0],axb[0][1],axb[1][0],axb[1][1]); line(axb[1][0],axb[1][1],axb[2][0],axb[2][1]); line(axb[2][0],axb[2][1],axb[3][0],axb[3][1]); line(axb[3][0],axb[3][1],axb[0][0],axb[0][1]); cx=(sqrt (2))/2.0; zhuan[0][0]=cx; zhuan[0][1]=cx; zhuan[1][0]=-cx; zhuan[1][1]=cx; for(i=0;i<4;i++) { for(j=0;j<3;j++) { s=0; for(k=0;k<3;k++) { s=s+axb[i][k]*zhuan[k][j]; } zaxb[i][j]=s; } } line(zaxb[0][0],zaxb[0][1],zaxb[1][0],zaxb[1][1]); line(zaxb[1][0],zaxb[1][1],zaxb[2][0],zaxb[2][1]); line(zaxb[2][0],zaxb[2][1],zaxb[3][0],zaxb[3][1]); line(zaxb[3][0],zaxb[3][1],zaxb[0][0],zaxb[0][1]); for(i=0;i<4;i++) { for(j=0;j<3;j++) { s=0; for(k=0;k<3;k++) { s=s+zaxb[i][j]*rpingyi[k][j]; } rp[i][j]=s; } } line(rp[0][0],rp[0][1],rp[1][0],rp[1][1]); line(rp[1][0],rp[1][1],rp[2][0],rp[2][1]); line(rp[2][0],rp[2][1],rp[3][0],rp[3][1]); line(rp[3][0],rp[3][1],rp[0][0],rp[0][1]); getch(); closegraph(); } 实验六直线段裁剪算法 一、实验学时: 4 二、实验类型: 验证性实验 三、实验要求和目的 掌握直线段裁剪算法的一般思想方法. 四、实验内容 画几条线段,利用裁剪算法实现特定的裁剪,并验证算法的正确性 1算法思路 P52 第一步: 编码。 设直线段的两个端点为P1(x1,y1)和P2(x2,y2),根据编码规则,可以求出P1和P2所在的代码c1和c2; 第二步: 判别。 根据c1和c2的具体值,可以有三种情况: 1)c1=c2=0,这表明两端点全在窗口内,则整个直线也在窗口内,应该保留; 2)c1&&c2! =0,表明两端点必定同处于某一边界的同一外侧,则整个直线全在窗口外,应该舍弃; 如不属于上面两种请况,表明直线有一部分在窗口内,又可以分为以下三种情况: (1)一个端点在内,一个端点在外; (2)两个端点均在外,但直线段中部跨越窗口; (3)两端点都在外,且直线段也在外。 第三步: 求交。 对不能确定取舍的直线段,求其与窗口边界及其延长线的交点,从而将直线段分割。 求交点时,可以有针对性地与某一确定边界求交。 在交点处把线段分为两段。 把其中一段完全在窗口外,舍弃之。 第四步: 对剩下的线段重复以上各步,可以验证,至多重复到第三遍的判断为止,这时剩下的直线段或者全在窗口内,或者全在窗口外,从而完成了对直线段的裁剪。 2.C程序代码 #include #include #definex1150 #definexr180 #defineyt180 #defineyb150 voidCohen_Sutherland(doublex0,doubley0,doublex2,doubley2) { intc,c1,c2; doublex,y; c1=makecode(x0,y0); c2=makecode(x2,y2); while(c1! ==1) { if(c1&c2==1) return; c=c1; if(c==0) c=c2; if(c&1==1) { y=y0+(y2-y0)*(x1-x0)/(x2-x0); x=x1; } else if(c&2) { y=y0+(y2-y0)*(x1-x0)/(x2-x0); x=xr; } else if(c&4) { y=y0+(y2-y0)*(x1-x0)/(x2-x0); y=yb; } else if(c&8) { y=y0+(y2-y0)*(x1-x0)/(x2-x0); y=yt; } if(c==c1) { x0=x; y0=y; c1=makecode(x,y); } else { x2=x; y2=y; c2=makecode(x,y); } } line(x0,y0,x2,y2); } intmakecode(doublex,doubley) { intc=0; if(x c=1; else if(x>x1) c=1; else if(x>xr) c=2; if(y c=c+4; else if(y>yt) { c=c+8; } returnc; } voidmain() { intdriver=DETCET; intmode; initgraph(&driver,&mode,""); Cohen_Sutherland(75,75,200,200); getch(); closegraph(); } 实验七两条线段求交算法 一、实验学时: 2 二、实验类型: 验证性实验 三、实验要求和目的 掌握线段求交的一般思想方法. 实现线段求交算法 四、实验内容 求两条线段的交点,并是函数适应性更广 1.算法思路 1)计算行列式: 若行列式=0,则两线段重合或平行,无交点,算法结束; 2)计算交点参数: 若 ,则无交点,算法结束 3)计算交点 2.C程序代码 2.源程序: #include #include voidmain() { intxa,ya,xb,yb,xc,yc,xd,yd,x,y,color; doublet1,t2,deater; intdriver=DETECT; intgmode; initgraph(&driver,&gmode,""); scanf("%d",&xa); scanf("%d",&ya); scanf("%d",&xb); scanf("%d",&yb); scanf("%d",&xc); scanf("%d",&yc); scanf("%d",&xd); scanf("%d",&yd); line(xa,ya,xb,yb); line(xc,yc,xd,yd); deater=-(xb-xa)*(yd-yc)+(xd-xc)*(yb-ya); if(deater==0) { printf("zhixianpingxing"); }else { t1=((xc-xa)*(yc-yd)-(xc-xd)*(yc-ya))/deater; t2=((xb-xa)*(yc-ya)-(xc-xa)*(yb-ya))/deater; if(0 { x=xa+t1*(xb-xa); y=ya+t1*(yb-ya); putpixel(x,y,4); printf("%d,%d",x,y); }else { printf("liangxianbuhuixiangjiao"); } } getch(); closegraph(); } 实验八点对简单多边形的包含 一、实验学时: 2 二、实验类型: 验证性实验 三、实验要求和目的 掌握包含判断一般思想方法. 实现点对简单多边形(五边形,自己定义顶点坐标) 四、实验内容 编程实现点对五边形的包含检查算法。 1.算法思路 首先通过给出点的坐标画出五边形,然后: 1)[准备] = = m=-1;i=0; 2)[排除必不相交的情形]若下列条件有一个成立,则到4。 并且 ; 并且; 并且 ; 3)[计算交点] ,分两种情况: 若y= ,则点P在多边形的边界上,算法结束; 若y< 则m=(-1).m; 4)[结束判断]i=i+1,若i 最后,从要判断的点,向下画直线,便于观察点在多边形内部,外部还是在边界上,并且同时输出英文句子,若再边界上则输出pointpisontheedgeofgraph若再内部则输出pointpisontheedgeofgraph,否则输出Pointpisinthegraph。 1.C程序代码 main() { intxx[10],yy[10],m,i,x0,y0,n,y; n=4; x0=600; y0=400; printf("pleaseputthepoints\n"); for(i=0;i { scanf("%d%d",&xx[i],&yy[i]); } m=-1; for(i=0;i { if(x0>xx[i]&&x0>=xx[i+1]||x0 { y=yy[i]+(x0-xx[i])*(yy[i+1]-yy[i])/(xx[i+1]-xx[i]); if(y==y0) printf("itisinthebound\n"); else { if(y m=-1*m; } } } if(m==-1) { printf("pisoutoftheduobianxing\n"); } if(m==1) { printf("pisintheduobianxing\n"); } getch(); } 实验九Bezier曲线 一、实验学时: 4 二、实验类型: 验证性实验 三、实验要求和目的 掌握Bezier曲线的一般性质 实现Bezier曲线的描绘 四、实验内容 实现Bezier曲线的画线算法 1.算法描述: 首先给定四个初始点,由公式可以得到计算n次Bezier曲线上控制点在t时的值P(t),可以归结为两个n-1次Bezier曲线在t时的线性组合。 t每增加一个步长,由递推计算关系可以得到一个对应的P(t)值,依次画出点(t,P(t)),则可以得到曲线 2.源程序: #include #include voidbezier(intdegree,intnpoints,doublecoeff1[],doublecoeff2[]) { doublet,delt; inti; delt=1.0/(double)npoints; t=0.0; for(i=0;i<=npoints;i++) { decas(degree,coeff1,coeff2,t); t+=delt; } } decas(intdegree,doublecoeff1[],doublecoeff2[],doublet) { intr,i; double*coeffa,coeffa10,coeffa20; doublecoeffa1[5],coeffa2[5]; for(i=0;i<=degree;i++) coeffa1[i]=coeff1[i]; coeffa2[i]=
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 图形学 实验 指导书