圆的生成算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
圆的生成算法
利用直线坐标法和极坐标法生成圆周颇费时间,而圆的Bresenham算法则简捷很多。一.圆的Bresenham算法思想:
设圆的半径为r,先考虑圆心在(0,0),并从x=0、y=r开始的顺时针方向的1/8圆周的生成过程。在这种情况下,x每步增加1,从x=0开始,到x=y结束。即有
X i+1=X i+1
相应地yi+1则在两种可能中选择:
Y i+1=y i或者y i+1=y i-1
选择的原则是考虑精确值y是靠近yi还是靠近yi-1,计算公式为
Y2=r2-(x i+1)2
d1=y i2-y2=y i2-r2+(x i+1)2
d2=y2-(y i-1)2=r2-(x i+1)2-(y i-1)2
令pi=d1-d2,并代入d1、d2,则有
P i=2(x i+1)2+y i2+(y i-1)2-2r2(1)
Pi称为误差。如果Pi<0,则yi+1=yi,否则yi+1=yi-1.pi的递归式为
P i+1=p i+4x i+6+2(y i+12-y i2)-2(y i+1-y i) (2)
P i的初值由式(1)代入xi=0,yi=r,而得
P1=3-2r (3)
根据上面的推导,圆周生成算法思想如下:
(1)求误差初值,p1=3-2r,i=1,画点(0,r);
(2)求下一个光栅位置,其中x i+1=x i+1,如果p i<0,则y i+1=y i,否则y i+1=y i-1;
(3)画点(x i+1,y i+1);
(4)计算下一个误差,如果p i<0,则p i+1=p i+4x i+6,否则p i+1=p i+4(x i-y i)+10;
(5)I=i+1,如果x=y,则结束,否则返回步骤2;
虽然(1)式表示p i+1的算法很复杂,但因为y i+1只能y i或y i-1,使得步骤(4)的算法变得简单,只需做加法和乘4的乘法。
圆的Bresenham算法的程序实现如下:
#include
#include
#include
#include
void BresenhemCircle(int centerx, int centery, int radius, int color, int type);
void initgr(void) /* BGI初始化*/
{
int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果*/ registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行*/ initgraph(&gd, &gm, "");
setbkcolor(WHITE);
}
int main(void)
{
int centerx,centery,radius,color,type;
printf("centerx,centery\n");
scanf("%d",¢erx);
scanf("%d",¢ery);
printf("radius\n");
scanf("%d",&radius);
printf("color,type\n");
scanf("%d",&color);
scanf("%d",&type);
initgr(); /*BGI初始化*/
BresenhemCircle(centerx,centery,radius,color,type);
getch();
closegraph();
}
void BresenhemCircle(int centerx, int centery, int radius, int color, int type)
{
int x =type= 0;
int y = radius;
int delta = 2*(1-radius);
int direction;
while (y >= 0) {
if (!type) {
putpixel(centerx+x, centery+y, color);
putpixel(centerx-x, centery+y, color);
putpixel(centerx-x, centery-y, color);
putpixel(centerx+x, centery-y, color);
}
else {
line(centerx+x, centery+y, centerx+x, centery-y);
line(centerx-x, centery+y, centerx-x, centery-y);
}
if (delta < 0) {
if ((2*(delta+y)-1) < 0) {
direction = 1;
}
else {
direction = 2;
}
}
else if(delta > 0) {
if ((2*(delta-x)-1) <= 0) {
direction = 2;
}
else {
direction = 3;
}
}
else {
direction=2;
}
switch(direction) {
case 1:
x++;
delta += (2*x+1);
break;
case 2:
x++;
y--;
delta += 2*(x-y+1);
break;
case 3:
y--;
delta += (-2*y+1);
break;
}
}
}
二.中心画圆法
圆的特性:八对称性。只要扫描转换八分之一圆弧,就可以求出整个圆弧的像素集。
考虑中心在原点半径为R的第二个8分圆,构造判别式
d=F(M)=(xp+1)2+(yp-0.5)2-R2
若d<0则下一个像素为P1,而且再下一个象素的判别式为
d=(Xp+2)2+(Yp-0.5)2-R2=d+2Xp+3
若d>=0则下一个像素为P2,而且再下一个像素的判别式为
d=(xp+2)2+(yp-1.5)2-R2=d+2(xp-yp)+5
初值F(1,R-0.5)=1.25-R
为了提高算法效率,可以将上面的浮点运算改为整数运算d0=1.25-R,用e=d-0.25代替d, e0=1-R,因为e为整数,所以e<-0.25等价于e<0,:算法描述: