计算机图形学上机.docx
- 文档编号:30064981
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:13
- 大小:157.07KB
计算机图形学上机.docx
《计算机图形学上机.docx》由会员分享,可在线阅读,更多相关《计算机图形学上机.docx(13页珍藏版)》请在冰豆网上搜索。
计算机图形学上机
目录
实验一中点算法3
一、实验目的和要求3
二、主要算法描述3
三、代码实现4
四、实验结果7
实验三Bezier曲线画茶壶8
一、实验目的和要求8
二、主要算法描述8
三、代码实现10
四、实验结果11
心得体会14
实验一中点算法
一、实验目的和要求
熟悉中点算法,能够运用中点算法画直线、圆或椭圆,程序实现中点画线。
二、主要算法描述
中点算法画椭圆:
中点椭圆算法与圆弧中点算法类似,主要在于使用判别式判断下一个像素点的值。
具体就是首先确定一个象素,接着在选定的中点计算一个判别式的值,由判别式的符号确定两个候选象素中更近的象素点。
椭圆方程:
F(x,y)=b2x2+a2y2–a2b2=0;
其中a,b分别为x与y轴的长短半轴长;
椭圆具有四分对称性,故可只讨论第一象限椭圆弧的生成;
椭圆上(x,y)处的法向量为:
N(x,y)=2b2x+2a2y;
根据法向量的x、y分量的大小,把圆弧分为上下两部分,上半部当前中点法向量(2b2(xp+1),2a2(yp-0.5))的y分量大于x分量;当y分量小于x分量时,转入下半部,下半部的中点为(xp+0.5,yp-1);
第一象限椭圆弧以切线斜率为-1的点作为分界点分上下两部分:
讨论椭圆弧的上部分:
当前像素点为(Xp,Yp),选定中点为(Xp+1,Yp-0.5),构造判别式如下:
d1=F(Xp+1,Yp-0.5)=b2(Xp+1)2+a2(Yp-0.5)2-a2b2
根据d1的符号来决定下一像素是取正右方(Xp+1,Yp),还是右下方(Xp+1,Yp-1):
1、若d1<0,中点在椭圆内,取正右方象素,判别式更新为:
d1'=F(Xp+2,Yp-0.5)=d1+b2(2Xp+3)
d1的增量为b2(2Xp+3)
2、当d1≥0,中点在椭圆外,取右下方象素,更新判别式:
d1'=F(Xp+2,Yp-1.5)=d1+b2(2Xp+3)+a2(-2Yp+2)
d1的增量为b2(2Xp+3)+a2(-2Yp+2)
3、d1的初始条件:
椭圆弧起点为(0,b),故第一个中点为(1,b-0.5)
初始判别式:
d10=F(1,b-0.5)=b*b+a*a(-b+0.25)
讨论椭圆弧的下部分:
移出上部分的条件:
dy/dx<=-1,即a2y>=b2x
构造判别式为:
d2=F(Xp+0.5,Yp-1)
=b2(Xp+0.5)2+a2(Yp-1)2-a2b2
迭代判断:
1、若d2<0,则取下一象素是一右下方(Xp+1,Yp-1)
d2’=F(Xp+1.5,Yp-2)=d2+b2(2Xp+2)+a2(-2Yp+3)
2、若d2>=0,则下一象素可能是一正下方(Xp,Yp-1)
d2’=F(Xp+0.5,Yp-2)=d2+a2(-2Yp+3)
下半部分弧的终止条件为y=0
三、代码实现
在程序部分,使用了两种方法去画椭圆:
第一种是中点法画椭圆,核心函数为voidellipseMidpoint(intxCenter,intyCenter,intRx,intRy),其中椭圆圆心坐标(xCenter,yCenter),长短轴长度分别为Rx,Ry;画点函数ellipsePlotpoints(intxCenter,intyCenter,intx,inty),描出点(xCenter+x,yCenter+y);也尝试过画出实心椭圆,效果不够理想;
另一种是使用椭圆的参数函数法,通过不断画点形成椭圆(代码中是不断生成椭圆上相邻两点,与椭圆圆心连接成极小的三角形,最后形成的是实心椭圆),其核心函数为voidCompare(void);两种方法同时使用,形成对比。
方法一:
(使用中点算法画椭圆)
voidellipsePlotpoints(intxCenter,intyCenter,intRx,intRy)
{
glVertex2i(xCenter+Rx,yCenter+Ry);
glVertex2i(xCenter-Rx,yCenter+Ry);
glVertex2i(xCenter+Rx,yCenter-Ry);
glVertex2i(xCenter-Rx,yCenter-Ry);
}
voidellipseMidpoint(intxCenter,intyCenter,intRx,intRy)
{
intRx2=Rx*Rx;intRy2=Ry*Ry;inttwoRx2=2*Rx2;inttwoRy2=2*Ry2;
intp;
intx=0;
inty=Ry;
intpx=0;
intpy=twoRx2*y;
//画椭圆上半部分
p=Ry2-(Rx2*Ry)+(0.25*Rx2);//判别式
while(px { x++; px+=twoRy2; if(p<0) p+=Ry2+px; else{ y--; py-=twoRx2; p+=Ry2+px-py; } ellipsePlotpoints(xCenter,yCenter,x,y); } //画椭圆下半部分 p=Ry2*(x+0.5)*(x+0.5)+Rx2*(y-1)*(y-1)-Rx2*Ry2;//判别式 while(y>0) { y--; py-=twoRx2; if(p>0) { p+=Rx2-py; } else{ x++; px+=twoRy2; p+=Rx2-py+px; } ellipsePlotpoints(xCenter,yCenter,x,y); } } 方法二: (参数方程法) voidCompare(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.7,0.0,1.0);//设置画线的颜色(蓝色,三维浮点型) glBegin(GL_TRIANGLE_FAN); glVertex3d(50,50,0.2); for(doublei=0;i<1000;i+=0.1)//1000次循环 glVertex3d(30*cos(i)+50,20*sin(i)+50,0);//以(50,50)为中心,30,20分别为长短轴画椭圆 glEnd(); glFlush(); } 四、实验结果 使用方法一的运行结果如下图: 使用方法二的运行结果如下图: 实验三Bezier曲线画茶壶 一、实验目的和要求 掌握使用Bezier曲线画茶壶的算法 二、主要算法描述 首先,在做这个实验之前,我们必须了解使用Bezier曲线拟合的原理与思想,Bezier基函数的定义: 如下n次多项式称为n次Bezier基函数 其中: Bezier曲线的定义: 下列n次多项式曲线P(t)称为n次Bezier曲线 为了深刻理解其控制点的含义,我首先对课本上的范例进行了尝试,得到了使用4个控制点得到1条Bezier曲线的方法。 对于实现茶壶,主要考虑怎样实现壶体,壶盖,壶底,把手与壶嘴。 壶体: 旋转面;基本曲线用分段三次Bezier曲线描述,由10个控制点控制三段曲线,10点坐标见表a。 a X Z 1 1.4000 2.25000 2 1.3375 2.38125 3 1.4375 2.38125 4 1.5000 2.25000 5 1.7500 1.72500 6 2.0000 1.20000 7 2.0000 0.75000 8 2.0000 0.30000 9 1.5000 0.07500 10 1.5000 0.00000 表a壶体的7个控制点坐标 壶盖: 旋转面;轮廓线由两段三次Bezier曲线组成。 7点坐标见表b。 b X Z 1 0.0 3.00 2 0.8 3.00 3 0.0 2.70 4 0.2 2.55 5 0.4 2.40 6 1.3 2.40 7 1.3 2.25 表b壶盖的7个控制点坐标 壶底: 一平面圆,半径为1.5000。 把手与壶嘴: 用Bezier曲面表示,剖面的外轮廓线有两条,每条有两段7个控制点,Y值为0.0,然后再增加两条外轮廓线,它们的X、Z坐标与前同,只是Y不同。 即实际由两片加对称的两片(-Y)组成。 但是如果根据课件中给出的数据会导致画出一个把手和壶嘴向外的不对称茶壶,这是由于其Y坐标的原因,在实现中可以将Y坐标平分,为-y和y即可达到对称的目的。 三、代码实现 程序中使用函数binomialCoeffs()和beziercommon()计算Bezier的基函数BEZi,n(t),然后使用函数computeBezPt()来根据控制点的坐标计算其Bezier函数。 壶体、壶盖、壶底的算法: 对于壶体,主要函数为voiddrawTeapotBody(),通过给出Bezier曲线并旋转得到壶体。 对于壶盖,主要函数为voiddrawTeapotTop(),也是使用旋转的思想得到壶盖,壶底的实现较为简单,主要函数为voiddrawTeapotBottom(),就是一个半径为1.5000的平面圆,这一部分教员给了参考代码,为画壶嘴和壶把做出指导。 画壶体、壶盖的步骤如下: 1、首先采用bezier曲线原理编程绘制一条bezier曲线。 a.通过distance函数计算给定控制点间的折线距离d,若d大于所要求的上限,则将该控制点进行差分得到两倍于原来的控制点数,并分成两组,转b。 否则绘制图线,此程序中每段曲线绘制100个点。 b.对于两组控制点,继续递归调用。 执行a。 2、将每两段间的分割点记录,便于后面绘制水平圆面。 3、将第一步中绘制的曲线进行旋转,得到纵向网格线,本程序中采用了纵向360度总共的20条线,每隔18度旋转一次。 4、用上面三步所述相同的方法来绘制壶体和壶底。 5、加入鼠标控制和键盘控制,同时自动更改视点,实现可旋转。 这样执行的结果是一个无把和嘴的壶,如下: 壶把、壶嘴实现的算法: 程序中主要有以下函数用来实现壶嘴和壶把,实现壶嘴的函数有: voiddrawTeapotMouth17011();voiddrawTeapotMouth17012(); voiddrawTeapotMouth17021();voiddrawTeapotMouth17022(); 实现壶把的函数有: voiddrawTeapotMouth16011();voiddrawTeapotMouth16012(); voiddrawTeapotMouth15021();voiddrawTeapotMouth15022(); 壶把、壶嘴用Bezier曲面表示,剖面的外轮廓线有两条,每条有两段7个控制点,Y值为0.0,然后再增加两条外轮廓线,它们的X、Z坐标与前同,只是Y不同。 Y值代表了向外的位移,但是如果根据课件中给出的点的坐标会导致画出一个把手和壶嘴向外的不对称茶壶,这是由于其Y坐标的原因(课件中的数据是0.0到Y),在实现中可以将Y坐标平分,为-y和y即可达到对称的目的。 旋转思想来源于壶体的旋转实现,壶体一共旋转360度成为一个圆,这里对于壶嘴,只需旋转一个相对较小的角度即可达到一个看起来“正确”的壶嘴, 在这里,degree=2*M_PI*jj/300;0<=jj<20,所以共旋转了24度,20条曲线。 使用同样方法可以画出壶把。 四、实验结果 经调试,最终得到的茶壶如下: 俯视图: 最初程序运行的结果,没有鼠标功能,正面图: 心得体会 经过这次计算机图形学的上机实验,在编程、调试的过程中,我对计算机图形学的理解认识更深了,对于OpenGL绘图工具的使用也有了实践练习,那些生动有趣的图形引人入胜,我确实体会到了图形学的魅力。 相信经过本次实验,我对图形编程的知识掌握得更加牢固,为今后的学习工作打下更好的基础。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机 图形学 上机