椭圆中点Bresenham算法.docx
《椭圆中点Bresenham算法.docx》由会员分享,可在线阅读,更多相关《椭圆中点Bresenham算法.docx(12页珍藏版)》请在冰豆网上搜索。
椭圆中点Bresenham算法
一、设计题目2
二、设计要求2
三、设计方案2
四、程序流程图6
五、程序清单7
六、程序运行结果分析15
七、系统不足及改进方案15
八、设计总结16
、设计题目:
椭圆中点Bresenham算法
二、设计要求:
1、要求有两种输入方式:
(1)输入椭圆的长短轴来生成椭圆;
(2)根据输入点来生成椭圆并输出椭圆的长短轴;
2、椭圆的颜色为红色;
三、设计方案:
1、椭圆对称性质:
椭圆分别关于X轴、丫轴对称。
因此在计算椭圆生成的时候,只需要计算1/4个椭圆,经过对称原理就可以实现其他3/4个椭圆的生成了,即:
计算出目标点(x,y)的坐标,必然存在(x,-y)、(-x,y)(-x,-y)。
此方案中采用计算第一象限中椭圆的生成,即:
计算x=0到y=0的1/4的椭圆。
先通过平移的方法将假设椭圆中心在坐标原点,然后计算,最后再平移到真实中心位置。
2、对于第一象限的椭圆,斜率k=-(b*b)*x/(a*a)*y,当x率k的绝对值小于1,计算时在x方向上取单位量;当x>y时,斜率k的绝
对值大于1,计算时在y方向上取单位量。
记:
xy的区域为第二区域。
3、输入方式一:
输入椭圆的长短轴来生成椭圆。
已知:
长短半轴分别为a、b,计算的初始位置为(0,b)。
22乞红1
22
椭圆的方程为:
ab。
令F(x,y)=b*b*x*x+a*a*y*y-a*a*b*b=0
(1)对于第一区域,如图1所示,P点坐标为(冷,yp)、P1(Xp+1,yp)
为P点正右边的点、P2(Xp+1,yp-1)为P点右下方的点,M(Xp+1,yp-o.5)
为P1、P2的中点。
图1第一区域示意图
令d=F(M)=F(Xp+1,yp-0.5)=b*b+a*a*(b-0.5)*(b-0.5)-a*a*b*b
当Xp=o、yp=b时,d的初始值为:
d=b*b-a*a*b+1/4a*a
&>=0时,应取P2作为下一个像素点,则其正右方的点的坐标为(Xp+2,yp-1),右下方的点的坐标为(Xp+2,yp-2),中点坐标为(Xp+2,yP-1.5)。
此时,d=F(M)=F(Xp+2,yp-1.5)=d+b*b*(2*Xp+3)-2a*a*(yp-1)
2d此时,d=F(M)=F(Xp+2,yp-0.5)=d+2*b*b*Xp+3*b*b
(2)对于第二区域,如图2所示,p点坐标为(Xp,yp),pi(Xp,yp-1)为p点正下方的点、P2(Xp+1,yp-1)为p点右下方的点,M(Xp+0.5,yp-1)为Pi、P2的中点。
图2第二区域示意图
令d=F(M)=F(Xp+0.5,yp-1)=b*b*(Xp+0.5)*(Xp+0.5)+a*a*(yp-1)
*(yp-1)-a*a*b*b
设p坐标的初始值为Xp=Xo,yp=y。
Xo=yo
d的初始值为:
d=F(Xo+O.5,yo-1)=b*b*(Xo+O.5)*(Xo+O.5)+a*a*(y°-1)*(y°-1)-a*a*b*b
⑪>=O时,应取P1作为下一个像素点,则其正下方的点的坐标为(Xp,yP-2),右下方的点的坐标为(Xp+i,yP_2),中点坐标为(Xp+O.5,yp-2)。
此时,d=F(M)=F(Xp+O.5,yp-2)=d+a*a*(3-2*yp)
2d<0时,应取P2作为下一个像素点,则其正下方的点的坐标为(Xp+1,yp-2),右下方的点的坐标为(Xp+2,yP-2),中点坐标为(知+1.5,yP-2)。
此时,d=F(M)=F(Xp+1.5,yP-2)=d+2*b*b*(Xo+1)+a*a*(3-2*yp)
(3)根据对称性原理计算其他3个象限的坐标。
输入方式二:
根据输入点来生成椭圆并输出椭圆的长短轴。
已知:
两点坐标(Xi,%)、(X2,y2)
22乞L1
22设椭圆的方程为:
ab
将两点坐标(Xi,yi)、(X2,y2)代人椭圆方程中,得出a、b的值分别为:
2222222a2=(X2*yi-Xi*y2)/(yi-y2)
2222222b2=(Xi*y2-X2*yi)/(Xi-X2)
然后按照方式一生成所求椭圆。
四、程序流程图
输入方式一的流程图如图3所示:
输入方式二的流程图如图4所示:
图3输入方式一流程图
图4输入方式二流程图
五、程序清单
//zhongdiansuanfa.cpp:
Definestheentrypointfortheconsoleapplication.
#inelude"stdafx.h"
#include
#include
#include
#includeinta;
intb;
/*定义长短半轴分别为a、b*/
voidGetValue()
{
intinput=O;
intx1,x2,y1,y2;
\n");
printf("请输入中点算法产生的方式:
printf("1.输入椭圆长短半径\n");
printf("2.输入椭圆坐标\n");
/*输出两种输入方式*/
scanf("%d",&input);
if(input==1)
{
printf("请输入a的值:
\n");
scanf("%d",&a);
printf(”请输入b的值:
\n");
scanf("%d",&b);
}
if(input==2)
{
printf("请输入第一个坐标的值:
\n");
scanf("%d,%d",&x1,&y1);
printf("请输入第二个坐标的值:
\n");
scanf("%d,%d",&x2,&y2);
a=sqrt((y1*y1*x2*x2-x1*x1*y2*y2)/(y1*y1-y2*y2));
b=sqrt((x1*x1*y2*y2-x2*x2*y1*y1)/(x1*x1-x2*x2));
/*根据输入的两个坐标计算椭圆长短半轴a、b的值*/
printf("a=%d",a);
printf("b=%d",b);
/*输出长短半轴a、b的值*/
}
}
voidPointsEllipse(intx,inty)
{
glColor3f(1.0f,O.Of,O.Of);
/*生成的椭圆的颜色为红色*/
glPointSize
(1);
glBegin(GL_POINTS);
glVertex2i(x+200,y+200);
glVertex2i(-x+200,y+200);
glVertex2i(x+200,-y+200);
glVertex2i(-x+200,-y+200);
/*根据对称原理求出椭圆上各个点的坐标*/
glEnd();
voidmyDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f,O.Of,0.0f);
glBegin(GL_POINTS);
〃inta=200,b=100;
floatx,y,d1,d2;
x=0;
y=b;
/*第一区域的起始坐标*/
d仁b*b+a*a*(-b+0.25);
PointsEllipse(x,y);
/*计算第一区域椭圆上各个点的坐标*/
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--;
PointsEllipse(x,y);
}
/*计算第二区域椭圆上各个点的坐标*/
d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;
/*第二区域的起始点处的d值*/
while(y>0)
{
if(d2<0)
{
d2+=2*b*b*(x+1)-a*a*(2*y-3);
x++;
y--;
}
else
d2+=a*a*(-2*y+3);
y--;
}
PointsEllipse(x,y);
}
glEnd();
glFlush();
/*保证前面的OpenGL命令立即执行*/
}
voidInit()
{
GetValue();
glClearColor(0.0,0.0,0.0,0.0);
/*定义清空颜色设计为黑色*/
glShadeModel(GL_FLAT);
voidReshape©ntw,inth)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadldentity();
gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);
}
intmain(intargc,char*argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowPosition(100,100);
/*定义窗口在屏幕中的位置*/
glutlnitWindowSize(600,600);
/*定义窗口的大小*/
glutCreateWindow("zhongdiansuanfa!
");
/*根据前述设置的信息创建窗口*/
Init();
glutDisplayFunc(myDisplay);
glutReshapeFunc(Reshape);
glutMainLoop();
return0;
}
六、程序运行结果分析
运行该程序,窗口中显示:
请输入中点算法产生的方式:
1、输入椭圆长短半径。
2、输入椭圆坐标
输入1,并单击回车,显示请输入a的值,输入a的值,并单击回车,将显示请输入b的值,输入b的值,并单击回车,屏幕上将显示一个以a、b为长短半轴的红色椭圆;
输入2,并单击回车,将显示请输入第一个坐标的值,输入第一个坐标的值,并单击回车,将显示请输入第二个坐标的值,输入第二个坐标的值,并单击回车,屏幕上将显示一个以原点为中心,经过两个坐标的红色椭圆。
七、系统不足及改进方案
该算法生成的椭圆以原点为中心,如果要想实现椭圆的中心可放在任何位置,则在上述算法中通过平移的方法将假设圆心在坐标原点,然后计算,最后再平移到真实的中心位置。
假设椭圆的中心坐标为(x-center,y-center),则
00
10
center1
1
0
x'y'1=xy1xcentery
xcenterycenter
为平移向量
八、设计总结
回顾起此次计算机图形学课程设计,我仍感慨颇多,做这次课程设计之前我还自认为图形学这门课我学的还不错,但是当做设计时才发现原来还有这么多东西没有弄懂。
做完设计之后,感觉自己学到了很多很多的东西,同时不仅巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
通过这次课程设计使我懂得了理论与实际相结合是重要性,只有理论知识没有实践,一切都等于虚设,相当于纸上谈兵。
只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能提高自己的实际动手能力和独立思考的能力。
在设计过程中遇到的问题,可以说得是困难重重,在老师同学的帮助下最终成功完成了这次设计。
通过这次课程设计之后,不仅把以前所学过的知识重新温故了一遍,而且又从中学到了很多知识。
总的来说,这次设计的还是比较成功的,在设计中遇到了很多问题,最后在老师的辛勤的指导下,终于游逆而解,有点小小的成就感,觉得平时所学的知识有了实用的价值,达到了理论与实际相结合的目的,不仅学到了不少知识,而且锻炼了自己的能力,使自己对以后的路有了更加清楚的认识