📅  最后修改于: 2020-12-20 09:33:22             🧑  作者: Mango
使用Bresenham算法对圆进行扫描转换的工作方式如下:点从90°到45°生成,将仅沿+ x&-y方向移动,如图所示:
真实圆的最佳近似将由栅格中与真实圆的距离最小的那些像素描述。我们想从中产生点
90°至45°。假定最后的经扫描转换的像素是P 1 ,如图2所示。通过执行以下两个操作之一,可以找到最接近真实圆的每个新点。
令D(S i )是从原点到真圆平方的距离减去到点P 3平方的距离。 D(T i )是从原点到真圆平方的距离减去到点P 2平方的距离。因此,出现以下表达式。
D(S i )=(x i-1 +1) 2 + y i-1 2 -r 2
D(T i )=(x i-1 +1) 2 +(y i-1 -1) 2 -r 2
由于D(S i )将始终为+ ve&D(T i )将始终为-ve,因此可以将决策变量d定义如下:
d i = D(S i )+ D(T i )
因此,
d i =(x i-1 +1) 2 + y i-1 2 -r 2 +(x i-1 +1) 2 +(y i-1 -1) 2 -r 2
根据这个方程,我们可以将d i的初始值驱动为
如果假定圆以原点为中心,则第一步x = 0&y = r。
因此,
d i =(0 + 1) 2 + r 2 -r 2 +(0 + 1) 2 +(r-1) 2 -r 2
= 1 + 1 + r 2 -2r + 1-r 2
= 3-2r
此后,如果d_i <0,则仅x递增。
x i + 1 = x i + 1 d i + 1 = d i + 4x i +6
&如果d我≥0,则X和Y被递增
x i + 1 = x i + 1 y i + 1 = y i + 1
d i + 1 = d i + 4(x i -y i )+10
步骤1:开始算法
步骤2:声明p,q,x,y,r,d变量
p,q是圆心的坐标
r是圆的半径
步骤3:输入r的值
步骤4:计算d = 3-2r
步骤5:初始化x = 0
&nbsy = r
步骤6:检查整个圆是否已扫描转换
如果x> = y
停止
第7步:使用八向对称性概念绘制八个点。中心位于(p,q)。当前有效像素为(x,y)。
像素(x + p,y + q)
putpixel(y + p,x + q)
像素(-y + p,x + q)
像素(-x + p,y + q)
像素(-x + p,-y + q)
putpixel(-y + p,-x + q)
putpixel(y + p,-x + q)
putpixel(x + p,-yq)
步骤8:找到下一个要扫描像素的位置
如果d <0
然后d = d + 4x + 6
增量x = x + 1
如果d≥0
然后d = d + 4(x-y)+ 10
增量x = x + 1
递减y = y-1
步骤9:前往步骤6
步骤10:停止算法
示例:使用Bresenham算法绘制6个圆点。圆弧半径为10个单位时。圆的中心为(50,50)。
解:令r = 10(给出)
步骤1:取得起点(0,10)
d = 3-2r
d = 3-2 * 10 = -17
d <0 d = d + 4x + 6
= -17 + 4(0)+ 6
= -11
步骤2:绘制(1,10)
d = d + 4x + 6(∵d <0)
= -11 + 4(1)+ 6
= -1
步骤3:绘制(2,10)
d = d + 4x + 6(∵d <0)
= -1 + 4 x 2 + 6
= 13
步骤4:绘制(3,9)d> 0,因此x = x + 1,y = y-1
d = d + 4(xy)+ 10(∵d> 0)
= 13 + 4(3-9)+ 10
= 13 + 4(-6)+ 10
= 23-24 = -1
步骤5:绘制(4,9)
d = -1 + 4x + 6
= -1 + 4(4)+ 6
= 21
步骤6:绘制(5,8)
d = d + 4(xy)+ 10(∵d> 0)
= 21 + 4(5-8)+ 10
= 21-12 + 10 = 19
所以P 1 (0,0)⟹(50,50)
P 2 (1,10)⟹(51,60)
P 3 (2,10)⟹(52,60)
P 4 (3,9)⟹(53,59)
P 5 (4,9)⟹(54,59)
P 6 (5,8)⟹(55,58)
#include
#include
#include
#include
#include
void EightWaySymmetricPlot(int xc,int yc,int x,int y)
{
putpixel(x+xc,y+yc,RED);
putpixel(x+xc,-y+yc,YELLOW);
putpixel(-x+xc,-y+yc,GREEN);
putpixel(-x+xc,y+yc,YELLOW);
putpixel(y+xc,x+yc,12);
putpixel(y+xc,-x+yc,14);
putpixel(-y+xc,-x+yc,15);
putpixel(-y+xc,x+yc,6);
}
void BresenhamCircle(int xc,int yc,int r)
{
int x=0,y=r,d=3-(2*r);
EightWaySymmetricPlot(xc,yc,x,y);
while(x<=y)
{
if(d<=0)
{
d=d+(4*x)+6;
}
else
{
d=d+(4*x)-(4*y)+10;
y=y-1;
}
x=x+1;
EightWaySymmetricPlot(xc,yc,x,y);
}
}
int main(void)
{
/* request auto detection */
int xc,yc,r,gdriver = DETECT, gmode, errorcode;
/* initialize graphics and local variables */
initgraph(&gdriver, &gmode, "C:\\TURBOC3\\BGI");
/* read result of initialization */
errorcode = graphresult();
if (errorcode != grOk) /* an error occurred */
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1); /* terminate with an error code */
}
printf("Enter the values of xc and yc :");
scanf("%d%d",&xc,&yc);
printf("Enter the value of radius :");
scanf("%d",&r);
BresenhamCircle(xc,yc,r);
getch();
closegraph();
return 0;
}
输出: