计算机图形学圆的生成算法的实现.docx
《计算机图形学圆的生成算法的实现.docx》由会员分享,可在线阅读,更多相关《计算机图形学圆的生成算法的实现.docx(10页珍藏版)》请在冰豆网上搜索。
计算机图形学圆的生成算法的实现
计算机图形学--圆的生成算法的实现
实验三圆的生成算法的实现
班级信计学号51姓名程芳超分数
一、实验目的和要求:
1、掌握圆的生成算法的基本原理
2、熟悉圆的生成算法,利用Turbor实现中点画圆算法、圆的Bresenham算法。
二、实验内容:
1、熟悉圆上的8个对称点的算法,利用中点画圆算法画圆并在屏幕上显示出来;
2、使用Bresenham画圆法生成一个圆;
3、利用line()函数画圆:
.
圆的参数方程
;
圆心为o(x0,y0)。
以下为各程序的实现代码:
1、中点画圆算法:
运行结果为:
#include"Conio.h"
#include"graphics.h"
#include"stdio.h"
#include"math.h"
#defineclosegrclosegraph
#definexo300
#defineyo250
#defineDELTA1.0
#definemax100
typedefstruct
{
intx;inty;
}Point;
typedefstruct
{
intpointNum;
Point*vertices;
}Polygon;
voidinitgr(void)
{
intgd=DETECT,gm=0;
registerbgidriver(EGAVGA_driver);
initgraph(&gd,&gm,"");
}
voidputpixels(intx,inty,intcolor,intn)
{inti,j;
for(i=-n/2;i<=n/2;i++)
for(j=-n/2;j<=n/2;j++)
putpixel(x+j,y+i,color);
}
voidputpixelt(intx,inty,intcolor,inti)
{inta[8]={1,1,1,1,0,0,0,0};
if(a[i%8])putpixel(x,y,color);
}
voidEllipsePoints(intx,inty,intcolor)
{
putpixel(xo+x,yo+y,color);
putpixel(xo-x,yo+y,color);
putpixel(xo+x,yo-y,color);
putpixel(xo-x,yo-y,color);
}
voidCirclePoints(intx,inty,intcolor)
{
putpixel(xo+x,yo+y,color);
putpixel(xo+y,yo+x,color);
putpixel(xo-y,yo+x,color);
putpixel(xo-x,yo+y,color);
putpixel(xo+y,yo-x,color);
putpixel(xo+x,yo-y,color);
putpixel(xo-x,yo-y,color);
putpixel(xo-y,yo-x,color);
}
voidMidPointCircle1(intradius,intcolor)
{
intx,y;
floatd;
x=0;y=radius;d=5.0/4-radius;
CirclePoints(x,y,color);
while(y>x)
{
if(d<=0)
d+=2.0*x+3;
else
{
d+=2.0*(x-y)+5;
y--;
}
x++;
CirclePoints(x,y,color);
}
}
main()
{
initgr();
cleardevice();
MidPointCircle1(150,4);
getch();
closegraph();
}
运行结果为:
2圆的Bresenham算法:
#include
#include
#include
#include
voidBresenhamCircle(xc,yc,radius,color)
intxc,yc,radius,color;
{
intx,y,d;
x=0;
y=radius;
d=3-2*radius;
while(x{
plot_circle_points(xc,yc,x,y,color);
if(d<0)
d+=4*x+6;
else
{
d+=4*(x-y)+10;
y--;
}
x++;
}
if(x==y)
plot_circle_points(xc,yc,x,y,color);
}
plot_circle_points(xc,yc,x,y,color)
intxc,yc,x,y,color;
{
putpixel(xc+x,yc+y,color);
putpixel(xc-x,yc+y,color);
putpixel(xc+x,yc-y,color);
putpixel(xc-x,yc-y,color);
putpixel(xc+y,yc+x,color);
putpixel(xc-y,yc+x,color);
putpixel(xc+y,yc-x,color);
putpixel(xc-y,yc-x,color);
}
main()
{
inta,b,c,e;
intgraphdriver=DETECT;
intgraphmode=0;
initgraph(&graphdriver,&graphmode,"");
cleardevice();
a=300;
b=300;
c=150;
e=3;
BresenhamCircle(a,b,c,e);
getch();
closegraph();
}
运行结果为:
3、利用line()函数画圆
#include
#include
#include
#include
#include
main()
{
inti,r,xx[46],yy[46],x0,y0;
floatt=360/45*3.14/180;
intgdriver=DETECT,gmode;
initgraph(&gdriver,&gmode,"");
cleardevice();
setbkcolor(14);
setcolor(4);
x0=300;y0=250;r=200;
for(i=0;i<46;i++)
{
xx[i]=x0+r*cos(i*t);
yy[i]=y0-r*sin(i*t);
}
for(i=0;i<45;i++)
line(xx[i],yy[i],xx[i+1],yy[i+1]);
settextstyle(1,0,5);
outtextxy(300,200,"O");
line(300,250,500,250);
getch();
closegraph();
return0;
}
运行结果为:
三、实验结果分析
1、显示圆上的8个对称点的算法如下:
voidCirclePoints(intx,inty,intcolor)
{
putpixel(x,y,color);
putpixel(y,x,color);
putpixel(-x,y,color);
putpixel(y,-x,color);
putpixel(x,-y,color);
putpixel(-y,x,color);
putpixel(-x,-y,color);
putpixel(-y,-x,color);
}
若已知圆弧上一点(x,y),可以得到其关于4条对称轴的其他七个点,因此要扫描转换1/8圆弧就可以求出表示整个圆弧的像素集。
2、圆的Bresenham算法:
分析出来点(x,y),(x,-y),(-x,y),(-x,-y),(y,x),(y,-x),(-y,x),(-y,-x)的另外7个点。
关于中心画圆算法,通过计算x=0到x=y的1/8圆的范围,然后通过对称原理得到其他7/8个点的信息。
这里和Bresenham算法有很多相似之处,同样有一个决定下一个位置的关键值d来做权衡处理。
在中点画圆算法中,通过平移的方法将假设圆心在坐标原点,然后计算,最后再平移到真实原心位置。
3、在Bresenham算法中,只需做加法和乘4的乘法,因此远的Bresenham算法运行速度很快,适宜在硬件上实现。
4、t的值不同,所画圆的圆滑程度不同,圆心位置可随坐标改变。
5、两种算法生成一点所需的计算量比较
每种循环中各种运算次数
总和
画一个八分或四分圆的总运算次数
画每一点所需要的平均运算次数
比较
加法
移位
Bresenham法
2(d<0)
2
1
5
(R-R/
)
6+(
1)
5=R
R
2(d>=0)
3
1
6
中点算法
2(d<0)
2
1
5
(R-R/
)
7+(
1)
5=2R-3R/
5(2R-3R/
)/(R/
)
4.8
2(d>=0)
3
2
7
通过实际的程序运行进行比较,结论是中点画圆法速度比较快,就算法本身而言,该算法仍可以在某些方面进行改进,如其中的浮点运算改为整数运算等,执行速度将更快。
生成直线和圆这类基础算法在编程时要被无数次的调用,可能每生成一帧画面就要被调用成百上千次,因此其执行速度是至关重要的。
而这类基础算法的长度都很短,即使多用一些分支,多用一些变量和语句,一般来说只不过是增加几十个语句,这样的空间增加与算法极其重要的速度来比较是相对次要的因素。
因此在开发图形学的基础算法时,如果有可能提高算法的速度,应不惜多占用一些存储空间。