计算机图形学实验报告实验2.docx
《计算机图形学实验报告实验2.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验报告实验2.docx(14页珍藏版)》请在冰点文库上搜索。
计算机图形学实验报告实验2
贵州大学实验报告
学院:
计算机科学与信息学院专业:
计算机科学与技术班级:
10级计科101班
姓名
吴晨
学号
1008060248
实验组
实验时间
2013-6-10
指导教师
吴云
成绩
实验项目名称
实验二椭圆生成算法
实验目的
通过本实验,使学生了解并掌握在光栅显示系统中圆、椭圆的生成和显示算法,进一步熟悉相关开发平台。
实验要求
1、优化后的算法:
二次差分法
2、可任意指定圆心坐标。
3、书写实验报告:
(1)给出算法描述,包括理论、算法和数据结构;
(2)根据算法和数据结构:
编制源程序;
(3)给出实验数据和结果
(4)编制源程序;
3、对于一些较为重要的算法,可以适当给出代码
实验原理
一、生成园弧的中点算法
算法原理:
画出第二个八分园(45°-90°),利用八对称性画出其它八分园。
1.用中点算法画第二个八分园。
从当前已获得的象素递推出下一个象素。
园弧的隐函数的形式为
F(x,y)=x2+y2-R2=0
则园弧的正负划分性为:
F(x,y)>0,(x,y)在园外;
F(x,y)<0,(x,y)在园内;
F(x,y)=0,(x,y)在园上。
设(xi,yi)为已确定的象素坐标,则下一个象素只能是正右方的E点或右下方的SE点。
设M是E和SE的中点,M=(xi+1,yi-0.5):
如F(M)<0,则M在园内,说明E距离圆弧更近,下一点取正右方E点;
如F(M)>0,则M在园外,说明SE距离圆弧更近,下一点取右下方SE点;
如F(M)=0,则M在园上,下一点取E点或SE点。
构造判别式:
d=F(M)=F(xi+1,yi-0.5)=(xi+1)2+(yi-0.5)2-R2
(1)d<0,中点在圆内,选正右方的E点,再下一个象素的判别式为:
dnew=F(xi+2,yi-0.5)=(xi+2)2+(yi-0.5)2-R2=d+(2xi+3)
沿正右方向,d的增量为:
(2)d>=0,中点在圆外,选右下方的SE点,再下一个象素的判别式为:
dnew=F(xi+2,yi-1.5)=(xi+2)2+(yi-1.5)2-R2=d+(2xi+3)+(-yi+2)
=d+2(xi-yi)+5
沿右下方向,d的增量为:
(3)d初始值为:
d0=F(1,R-0.5)=1+(R-0.5)2-R2=1.25-R
在d的运算中包含了浮点数的运算,为了消除d中的浮点数运算,分析上述算法,可以看出,算法中取作用的只是d的符号,所以可设另一整数变量h:
h=d-0.25
所以:
初始化运算d0=1.25–R对应于:
h0=1-R
判别式d<0对应于h<-0.25
又因为:
h的初值h0为整数,运算过程中的分量也为整数(∆E和∆SE为整数),故h始终为整数。
所以可用h代替d作判断。
其初始值:
h0=d0-0.25=(1.25-R)-0.25=1-R
有以下对应关系:
h<0d<0
h>0d>0
h=0d=0
算法分析:
二阶差分法:
利用二阶差分降低增量的阶数
二阶差分(降低增量的阶数,用差分法消除中点算法中的乘法运算)。
中点算法中:
1,如在现有点p(xp,yp)上,对p+1点选择了E(xp+1,yp)点
(1)增量ΔE
二阶差分增量为:
(2)增量ΔSE
2,如在现有点p(xp,yp)上,对p+1点选择了SE(xp+1,yp-1)点
(1)
增量ΔE
x
y
d
E
SE
x=x+1(d<0)
d+E
E+2
SE+2
x=x+1(d>0)
y-1
d+SE
SE+4
算法步骤:
1,依据上一次迭代中的d的符号来选择现在点E或SE(d0=1-R);
2,用在上一次迭代计算的和来计算新的d;
3,用移到新象素点的二次差分值,并用它来更新和移到下一点。
二、椭圆中点算法
中点算法可以推广到一般二次曲线如椭圆。
中心在原点的椭圆方程为:
隐函数的形式为:
a=b时,该方程表示的是圆。
椭圆具有四对称性,可只考虑第一象限的椭圆弧。
椭圆上任一点(x,y)处的法向量为:
如在p点法线两分量相等,则p点将椭圆第一象限分成两部份,上半部份法向量在y方向的分量比x方向的大,在下半部份相反。
在p点:
在当前中点处,法向量(2b2(Xp+1),2a2(Yp-0.5))的y分量比x分量大,即:
b2(Xp+1)而在下一中点,不等式改变方向,则说明椭圆弧从上部分转入下部分。与圆弧中点算法类似:确定一个象素Pi后,接着在下两个候选象素的中点计算一个判别式d=F(M)的值,由判别式的符号确定更近的点。1.先讨论椭圆弧的上半部分(令△x=1)设Pi(xi,yi)已确定,则下一对待选像素的中点是:M(xi+1,yi-0.5)对初始点(0,b),第一个中点为(1,b-0.5),则:(1)当d<0(取T点)时,下一点(i+1)点的坐标为(xi+1,Yi),为确定i+2点取的下一个中点M的坐标为:(xi+2,yi-0.5)(2)当d>=0(取B点)时,下一点(i+1)点的坐标为(xi+1,Yi-1),为确定i+2点取的下一个中点M的坐标为:(xi+2,Yi-1.5) 2.在每一次迭代中都要判断椭圆是否已从上半部进入了下半部,如果b2x>=a2y,则椭圆进入下半部份,此时令△y=1,且:(1)若d<0,取右下方像素R,则 (2)若d>=0,取正下方像素L,则 3.终止条件为:y=0MidpointEllipe(a,b,color)inta,b,color;{intx,y;floatd1,d2;x=0;y=b;d1=b*b+a*a*(-b+0.25);putpixel(x,y,color);while(b*b*(x+1){{if(d1<0)d1+=b*b*(2*x+3);x++;}else{d1+=(b*b*(2*x+3)+a*a*(-2*y+2))x++;y--;}putpixel(x,y,color);}//上部分d2=sqr(b*(x+0.5))+sqr(a*(y-1))–sqr(a*b);while(y>0){if(d2<0){d2+=b*b*(2*x+2)+a*a*(-2*y+3);x++;y--;}else{d2+=a*a*(-2*y+3);y--;}putpixel(x,y,color);}//下部分}算法优化(提示):联解以下方程:得到椭圆上、下部分分界点P的坐标为:(1)令x由0→Px,y由0→Py,从而避免上述算法中反复计算循环中止条件。(2)采用增量算法,避免在计算d时的乘法和平方运算。实验环境硬件平台:PC软件:VisualC++6.0实验步骤1.掌握算法原理;2.依据算法,编写源程序并进行调试;3.对运行结果进行保存与分析;4.把源程序以文件的形式提交;5.按格式书写实验报告。实验内容实现圆、椭圆的中点算法。实验结果1、选择菜单项圆的中点画圆2、选择菜单项椭圆的中点画椭圆3、画出圆和椭圆的结果如下:4、可以改变相应的半径画出不同的圆和椭圆5、实现圆的生成算法,运用到二次差分法,减少算法的复杂度。实验总结本实验是利用中点算法生成圆和椭圆。在实验的过程中,我对中点画圆算法和中点画椭圆算法的理解更深入了。当我们在利用上述算法实现圆和椭圆的生成时,必须给出圆的半径和椭圆的长半径与短半径。源代码1、中点算法绘制圆voidCShiyan2View::OnMidpointcircle(){//TODO:AddyourcommandhandlercodehereCDC*pDC=GetDC();intxc=250,yc=150,r=100,c=0;intx,y;floatd;x=0;y=r;d=1.25-r;pDC->SetPixel((xc+x),(yc+y),c);pDC->SetPixel((xc-x),(yc+y),c);pDC->SetPixel((xc+x),(yc-y),c);pDC->SetPixel((xc-x),(yc-y),c);pDC->SetPixel((xc+y),(yc+x),c);pDC->SetPixel((xc-y),(yc+x),c);pDC->SetPixel((xc+y),(yc-x),c);pDC->SetPixel((xc-y),(yc-x),c);while(x<=y){if(d<0)d+=2*x+3;else{d+=2*(x-y)+5;y--;}x++;pDC->SetPixel((xc+x),(yc+y),c);pDC->SetPixel((xc-x),(yc+y),c);pDC->SetPixel((xc+x),(yc-y),c);pDC->SetPixel((xc-x),(yc-y),c);pDC->SetPixel((xc+y),(yc+x),c);pDC->SetPixel((xc-y),(yc+x),c);pDC->SetPixel((xc+y),(yc-x),c);pDC->SetPixel((xc-y),(yc-x),c);}}2、中点算法绘制椭圆voidCShiyan2View::OnMidpointellispe(){//TODO:AddyourcommandhandlercodehereCDC*pDC=GetDC();inta=250,b=100,xc=400,yc=300,c=0;intx,y;doubled1,d2;x=0;y=b;d1=b*b+a*a*(-b+0.25);pDC->SetPixel(x+300,y+200,c);pDC->SetPixel(-x+300,y+200,c);pDC->SetPixel(x+300,-y+200,c);pDC->SetPixel(-x+300,-y+200,c);while(b*b*(x+1){if(d1<0){d1+=b*b*(2*x+3);x++;}else{d1+=b*b*(2*x+3)+a*a*(-2*y+2);x++;y--;}pDC->SetPixel(x+xc,y+yc,c);pDC->SetPixel(-x+xc,y+yc,c);pDC->SetPixel(x+xc,-y+yc,c);pDC->SetPixel(-x+xc,-y+yc,c);}d2=sqrt(b*(x+0.5))+a*(y-1)-a*b;while(y>0){if(d2<0){d2+=b*b*(2*x+2)+a*a*(-2*y+3);x++;y--;}else{d2+=a*a*(-2*y+3);y--;}pDC->SetPixel(x+xc,y+yc,c);pDC->SetPixel(-x+xc,y+yc,c);pDC->SetPixel(x+xc,-y+yc,c);pDC->SetPixel(-x+xc,-y+yc,c);}}指导教师意见 签名:年月日注:可根据教学需要对以上栏目进行增减。表格内容可根据内容扩充。
而在下一中点,不等式改变方向,则说明椭圆弧从上部分转入下部分。
与圆弧中点算法类似:
确定一个象素Pi后,接着在下两个候选象素的中点计算一个判别式d=F(M)的值,由判别式的符号确定更近的点。
1.先讨论椭圆弧的上半部分(令△x=1)
设Pi(xi,yi)已确定,则下一对待选像素的中点是:
M(xi+1,yi-0.5)
对初始点(0,b),第一个中点为(1,b-0.5),则:
(1)当d<0(取T点)时,下一点(i+1)点的坐标为(xi+1,Yi),为确定i+2点取的下一个中点M的坐标为:
(xi+2,yi-0.5)
(2)当d>=0(取B点)时,下一点(i+1)点的坐标为(xi+1,Yi-1),为确定i+2点取的下一个中点M的坐标为:
(xi+2,Yi-1.5)
2.在每一次迭代中都要判断椭圆是否已从上半部进入了下半部,如果b2x>=a2y,则椭圆进入下半部份,此时令△y=1,且:
(1)若d<0,取右下方像素R,则
(2)若d>=0,取正下方像素L,则
3.终止条件为:
y=0
MidpointEllipe(a,b,color)
inta,b,color;
{intx,y;floatd1,d2;
x=0;y=b;
d1=b*b+a*a*(-b+0.25);
putpixel(x,y,color);
while(b*b*(x+1){{if(d1<0)d1+=b*b*(2*x+3);x++;}else{d1+=(b*b*(2*x+3)+a*a*(-2*y+2))x++;y--;}putpixel(x,y,color);}//上部分d2=sqr(b*(x+0.5))+sqr(a*(y-1))–sqr(a*b);while(y>0){if(d2<0){d2+=b*b*(2*x+2)+a*a*(-2*y+3);x++;y--;}else{d2+=a*a*(-2*y+3);y--;}putpixel(x,y,color);}//下部分}算法优化(提示):联解以下方程:得到椭圆上、下部分分界点P的坐标为:(1)令x由0→Px,y由0→Py,从而避免上述算法中反复计算循环中止条件。(2)采用增量算法,避免在计算d时的乘法和平方运算。实验环境硬件平台:PC软件:VisualC++6.0实验步骤1.掌握算法原理;2.依据算法,编写源程序并进行调试;3.对运行结果进行保存与分析;4.把源程序以文件的形式提交;5.按格式书写实验报告。实验内容实现圆、椭圆的中点算法。实验结果1、选择菜单项圆的中点画圆2、选择菜单项椭圆的中点画椭圆3、画出圆和椭圆的结果如下:4、可以改变相应的半径画出不同的圆和椭圆5、实现圆的生成算法,运用到二次差分法,减少算法的复杂度。实验总结本实验是利用中点算法生成圆和椭圆。在实验的过程中,我对中点画圆算法和中点画椭圆算法的理解更深入了。当我们在利用上述算法实现圆和椭圆的生成时,必须给出圆的半径和椭圆的长半径与短半径。源代码1、中点算法绘制圆voidCShiyan2View::OnMidpointcircle(){//TODO:AddyourcommandhandlercodehereCDC*pDC=GetDC();intxc=250,yc=150,r=100,c=0;intx,y;floatd;x=0;y=r;d=1.25-r;pDC->SetPixel((xc+x),(yc+y),c);pDC->SetPixel((xc-x),(yc+y),c);pDC->SetPixel((xc+x),(yc-y),c);pDC->SetPixel((xc-x),(yc-y),c);pDC->SetPixel((xc+y),(yc+x),c);pDC->SetPixel((xc-y),(yc+x),c);pDC->SetPixel((xc+y),(yc-x),c);pDC->SetPixel((xc-y),(yc-x),c);while(x<=y){if(d<0)d+=2*x+3;else{d+=2*(x-y)+5;y--;}x++;pDC->SetPixel((xc+x),(yc+y),c);pDC->SetPixel((xc-x),(yc+y),c);pDC->SetPixel((xc+x),(yc-y),c);pDC->SetPixel((xc-x),(yc-y),c);pDC->SetPixel((xc+y),(yc+x),c);pDC->SetPixel((xc-y),(yc+x),c);pDC->SetPixel((xc+y),(yc-x),c);pDC->SetPixel((xc-y),(yc-x),c);}}2、中点算法绘制椭圆voidCShiyan2View::OnMidpointellispe(){//TODO:AddyourcommandhandlercodehereCDC*pDC=GetDC();inta=250,b=100,xc=400,yc=300,c=0;intx,y;doubled1,d2;x=0;y=b;d1=b*b+a*a*(-b+0.25);pDC->SetPixel(x+300,y+200,c);pDC->SetPixel(-x+300,y+200,c);pDC->SetPixel(x+300,-y+200,c);pDC->SetPixel(-x+300,-y+200,c);while(b*b*(x+1){if(d1<0){d1+=b*b*(2*x+3);x++;}else{d1+=b*b*(2*x+3)+a*a*(-2*y+2);x++;y--;}pDC->SetPixel(x+xc,y+yc,c);pDC->SetPixel(-x+xc,y+yc,c);pDC->SetPixel(x+xc,-y+yc,c);pDC->SetPixel(-x+xc,-y+yc,c);}d2=sqrt(b*(x+0.5))+a*(y-1)-a*b;while(y>0){if(d2<0){d2+=b*b*(2*x+2)+a*a*(-2*y+3);x++;y--;}else{d2+=a*a*(-2*y+3);y--;}pDC->SetPixel(x+xc,y+yc,c);pDC->SetPixel(-x+xc,y+yc,c);pDC->SetPixel(x+xc,-y+yc,c);pDC->SetPixel(-x+xc,-y+yc,c);}}指导教师意见 签名:年月日注:可根据教学需要对以上栏目进行增减。表格内容可根据内容扩充。
{{if(d1<0)
d1+=b*b*(2*x+3);x++;}
else{d1+=(b*b*(2*x+3)+a*a*(-2*y+2))
x++;y--;}
}//上部分
d2=sqr(b*(x+0.5))+sqr(a*(y-1))–sqr(a*b);
while(y>0)
{if(d2<0){d2+=b*b*(2*x+2)+a*a*(-2*y+3);
x++;y--;}
else{d2+=a*a*(-2*y+3);y--;}
putpixel(x,y,color);}//下部分
}
算法优化(提示):
联解以下方程:
得到椭圆上、下部分分界点P的坐标为:
(1)令x由0→Px,y由0→Py,从而避免上述算法中反复计算循环中止条件。
(2)采用增量算法,避免在计算d时的乘法和平方运算。
实验环境
硬件平台:
PC
软件:
VisualC++6.0
实验步骤
1.掌握算法原理;
2.依据算法,编写源程序并进行调试;
3.对运行结果进行保存与分析;
4.把源程序以文件的形式提交;
5.按格式书写实验报告。
实验内容
实现圆、椭圆的中点算法。
实验结果
1、选择菜单项圆的中点画圆
2、选择菜单项椭圆的中点画椭圆
3、画出圆和椭圆的结果如下:
4、可以改变相应的半径画出不同的圆和椭圆
5、实现圆的生成算法,运用到二次差分法,减少算法的复杂度。
实验总结
本实验是利用中点算法生成圆和椭圆。
在实验的过程中,我对中点画圆算法和中点画椭圆算法的理解更深入了。
当我们在利用上述算法实现圆和椭圆的生成时,必须给出圆的半径和椭圆的长半径与短半径。
源代码
1、中点算法绘制圆
voidCShiyan2View:
:
OnMidpointcircle()
{
//TODO:
Addyourcommandhandlercodehere
CDC*pDC=GetDC();
intxc=250,yc=150,r=100,c=0;
intx,y;
floatd;
x=0;y=r;d=1.25-r;
pDC->SetPixel((xc+x),(yc+y),c);
pDC->SetPixel((xc-x),(yc+y),c);
pDC->SetPixel((xc+x),(yc-y),c);
pDC->SetPixel((xc-x),(yc-y),c);
pDC->SetPixel((xc+y),(yc+x),c);
pDC->SetPixel((xc-y),(yc+x),c);
pDC->SetPixel((xc+y),(yc-x),c);
pDC->SetPixel((xc-y),(yc-x),c);
while(x<=y)
{if(d<0)d+=2*x+3;
else{d+=2*(x-y)+5;y--;}
x++;
2、中点算法绘制椭圆
OnMidpointellispe()
inta=250,b=100,xc=400,yc=300,c=0;
doubled1,d2;
pDC->SetPixel(x+300,y+200,c);
pDC->SetPixel(-x+300,y+200,c);
pDC->SetPixel(x+300,-y+200,c);
pDC->SetPixel(-x+300,-y+200,c);
while(b*b*(x+1){if(d1<0){d1+=b*b*(2*x+3);x++;}else{d1+=b*b*(2*x+3)+a*a*(-2*y+2);x++;y--;}pDC->SetPixel(x+xc,y+yc,c);pDC->SetPixel(-x+xc,y+yc,c);pDC->SetPixel(x+xc,-y+yc,c);pDC->SetPixel(-x+xc,-y+yc,c);}d2=sqrt(b*(x+0.5))+a*(y-1)-a*b;while(y>0){if(d2<0){d2+=b*b*(2*x+2)+a*a*(-2*y+3);x++;y--;}else{d2+=a*a*(-2*y+3);y--;}pDC->SetPixel(x+xc,y+yc,c);pDC->SetPixel(-x+xc,y+yc,c);pDC->SetPixel(x+xc,-y+yc,c);pDC->SetPixel(-x+xc,-y+yc,c);}}指导教师意见 签名:年月日注:可根据教学需要对以上栏目进行增减。表格内容可根据内容扩充。
if(d1<0){
d1+=b*b*(2*x+3);
x++;}
else
{d1+=b*b*(2*x+3)+a*a*(-2*y+2);
x++;y--;
pDC->SetPixel(x+xc,y+yc,c);
pDC->SetPixel(-x+xc,y+yc,c);
pDC->SetPixel(x+xc,-y+yc,c);
pDC->SetPixel(-x+xc,-y+yc,c);
d2=sqrt(b*(x+0.5))+a*(y-1)-a*b;
if(d2<0){
d2+=b*b*(2*x+2)+a*a*(-2*y+3);
{d2+=a*a*(-2*y+3);
y--;}
指导教师意见
签名:
年月日
注:
可根据教学需要对以上栏目进行增减。
表格内容可根据内容扩充。
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2