【计算机图形学】中点画圆算法和Bresenham画圆算法

在平面解析几何中,圆的方程可以描述为(x – x0)2 + (y – y0)2 = R2,其中(x0, y0)是圆心坐标,R是圆的半径,特别的,当(x0, y0)就是坐标中心点时,圆方程可以简化为x2 + y2 = R2。在计算机图形学中,圆和直线一样,也存在在点阵输出设备上显示或输出的问题,因此也需要一套光栅扫描转换算法。为了简化,我们先考虑圆心在原点的圆的生成,对于中心不是原点的圆,可以通过坐标的平移变换获得相应位置的圆。

        在进行扫描转换之前,需要了解一个圆的特性,就是圆的八分对成性。如图(1)所示:

图(1)圆的八分对称性

圆心位于原点的圆有四条对称轴x = 0、y = 0、x = y和x = -y,若已知圆弧上一点P(x,y),就可以得到其关于四条对称轴的七个对称点:(x, -y)、(-x, y)、(-x, -y)、(y, x)、(y, -x)、(-y, x)、(-y, -x),这种性质称为八分对称性。因此只要能画出八分之一的圆弧,就可以利用对称性的原理得到整个圆。

 

1、  中点画圆法

        考虑圆心在原点,半径为R的圆在第一象限内的八分之一圆弧,从点(0, R)到点(R' , R' )顺时针方向确定这段圆弧。假定某点Pi(xi, yi)已经是该圆弧上最接近实际圆弧的点,那么Pi的下一个点只可能是正右方的P1或右下方的P2两者之一,如图(2)所示:

图(2)中点划线法示例

构造判别函数:

 

F(x, y)= x+ y– R2

 

当F(x, y)= 0,表示点在圆上,当F(x, y)> 0,表示点在圆外,当F(x, y)< 0,表示点在圆内。如果M是P1和P2的中点,则M的坐标是(xi + 1, yi – 0.5),当F(xi + 1, yi – 0.5)< 0时,M点在圆内,说明P1点离实际圆弧更近,应该取P1作为圆的下一个点。同理分析,当F(xi + 1, yi – 0.5)> 0时,P2离实际圆弧更近,应取P2作为下一个点。当F(xi + 1, yi – 0.5)= 0时,P1和P2都可以作为圆的下一个点,算法约定取P2作为下一个点。

现在将M点坐标(xi + 1, yi – 0.5)带入判别函数F(x, y),得到判别式d:

 

d = F(xi + 1, yi – 0.5)= (xi + 1)2 + (yi – 0.5)2 – R2

 

若d < 0,则取P1为下一个点,此时P1的下一个点的判别式为:

 

d’ = F(xi + 2, yi – 0.5)= (xi + 2)2 + (yi – 0.5)2 – R2

 

展开后将d带入可得到判别式的递推关系:

 

d’ = d + 2xi + 3

 

若d > 0,则取P2为下一个点,此时P2的下一个点的判别式为:

 

d’ = F(xi + 2, yi – 1.5)= (xi + 2)2 + (yi – 1.5)2 – R2

 

展开后将d带入可得到判别式的递推关系:

 

d’ = d + 2(xi - yi) + 5

 

特别的,在第一个象限的第一个点(0, R)时,可以推倒出判别式d的初始值d0

 

d0 = F(1, R – 0.5) = 1 – (R – 0.5)2 – R2 = 1.25 - R

 

根据上面的分析,可以写出中点画圆法的算法。考虑到圆心不在原点的情况,需要对计算出来的坐标进行了平移,下面就是通用的中点画圆法的源代码:

26 void MP_Circle(int xc , int yc , int r)

27 {

28     int x, y;

29     double d;

30 

31     x = 0;

32     y = r;

33     d = 1.25 - r;

34     CirclePlot(xc , yc , x , y);

35     while(< y)

36     {

37         if(< 0)

38         {

39             d = d + 2 * x + 3;

40         }

41         else

42         {

43             d = d + 2 * ( x - y ) + 5;

44             y--;

45         }

46         x++;

47         CirclePlot(xc , yc , x , y);

48     }

49 }

  参数xc和yc是圆心坐标,r是半径,CirclePlot()函数是参照圆的八分对称性完成八个点的位置计算的辅助函数。

2  改进的中点画圆法-Bresenham算法

        中点画圆法中,计算判别式d使用了浮点运算,影响了圆的生成效率。如果能将判别式规约到整数运算,则可以简化计算,提高效率。于是人们针对中点画圆法进行了多种改进,其中一种方式是将d的初始值由1.25 – R改成1 – R,考虑到圆的半径R总是大于2,因此这个修改不会影响d的初始值的符号,同时可以避免浮点运算。还有一种方法是将d的计算放大两倍,同时将初始值改成3 – 2R,这样避免了浮点运算,乘二运算也可以用移位快速代替,采用3 – 2R为初始值的改进算法,又称为Bresenham算法:

52 void Bresenham_Circle(int xc , int yc , int r)

53 {

54     int x, y, d;

55 

56     x = 0;

57     y = r;

58     d = 3 - 2 * r;

59     CirclePlot(xc , yc , x , y);

60     while(< y)

61     {

62         if(< 0)

63         {

64             d = d + 4 * x + 6;

65         }

66         else

67         {

68             d = d + 4 * ( x - y ) + 10;

69             y--;

70         }

71         x++;

72         CirclePlot(xc , yc , x , y);

73     }

74 }

  • 31
    点赞
  • 179
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值