得鹿梦鱼 得鹿梦鱼

圆的生成算法_中点画圆算法

考虑圆的对称性,可以有效的减少计算量,圆的形状在 每个象限中是相似的,因此瑞如果我们确定了再第一象限中圆的位置 ,就可以生成圆在xy平面中其他象限的部分,如下图

圆的对称性

我们仅需要计算的是从x=0x =0x=yx =y分段内的点就可以得到整个圆的所有像素位置
使用圆的参数方程和极坐标方式求解,仍然需要大量的计算时间,根据有效的画圆算法是如同bresenham画线算法一样以决策函数的增量计算为基础

为简单期间设原点坐标为坐标轴的中心点坐标
考虑绘制圆的方向为顺时针方向
如同光栅画线算法,我们在每个步中以单位间隔取样并确定离指定圆最近的像素位置,对于给定半径r,圆弧度为从x=0到x=y,曲线的斜率从0变化为-1,因此可以在该八分圆的正x方向去单位步长,使用决策函数来决定每一步中的两个可能得y值,那个更接近圆的位置
{fcirc=x2+y2r2<0在圆边界内fcirc=x2+y2r2=0在圆边界上fcirc=x2+y2r2>0在圆边界外\begin {cases}f_{circ} = x^2 + y^2 - r^2 < 0 \text{在圆边界内} \\f_{circ} = x^2 + y^2 - r^2 = 0 \text{在圆边界上} \\f_{circ} = x^2 + y^2 - r^2 > 0 \text{在圆边界外}\end {cases}

假设刚在xk,ykx_k,y_k上绘制了一个像素,下一个像素的位置则为xk+1,ykx_k + 1,y_k或者xk+1,yk1x_k+ 1,y_k - 1, 看那个更接近圆, 也就是距离xk+1,yk12x_k+1, y_k - \frac{1}{2}那个更近
pk=fcircxk+1,yk12=xk+12+yk122r2p_k = f_{circ}x_k+1, y_k - \frac{1}{2} = x_k+1^2 + y_k - \frac{1}{2}^2 - r^2
设定pk<0p_k< 0, 中点在圆内,yky_k接近圆边界,否则yk1y_k - 1接近圆边界
中点画圆算法
pk+1=xk+1+12+yk+1122r2p_{k+1} = x_{k+1}+1^2 + y_{k+1} - \frac{1}{2}^2 - r^2
pk+1=xk+22+yk+1122r2p_{k+1} = x_k+2^2 + y_{k+1} - \frac{1}{2}^2 - r^2
pk+1=xk2+2xk+4+yk+1122r2p_{k+1} = x_k^2 + 2x_k + 4 + y_{k+1} - \frac{1}{2}^2 - r^2

pk+1pk=xk2+4xk+4+yk+1122r2xk+12+yk122r2p_{k+1} - p_k = x_k^2 + 4x_k + 4 + y_{k+1} - \frac{1}{2}^2 - r^2 - x_k+1^2 + y_k - \frac{1}{2}^2 - r^2
pk+1pk=xk2+4xk+4+yk+1122r2xk2+2xk+1+yk122r2p_{k+1} - p_k = x_k^2 + 4x_k + 4 + y_{k+1} - \frac{1}{2}^2 - r^2 - x_k^2 + 2x_k + 1 + y_k - \frac{1}{2}^2 - r^2
pk+1pk=xk2+4xk+4+yk+1122r2xk22xk1yk122+r2p_{k+1} - p_k = x_k^2 + 4x_k + 4 + y_{k+1} - \frac{1}{2}^2 - r^2 - x_k^2 - 2x_k - 1 - y_k - \frac{1}{2}^2 + r^2
pk+1pk=3+2xk+yk+1122yk122p_{k+1} - p_k = 3 + 2x_k + y_{k+1} - \frac{1}{2}^2 - y_k - \frac{1}{2}^2
pk+1pk=3+2xk+yk+12yk+1+14yk2yk+14p_{k+1} - p_k = 3 + 2x_k + y_{k+1}^2 - y_{k+1} + \frac{1}{4} - y_k^2 - y_k + \frac{1}{4}
pk+1pk=3+2xk+yk+12yk+1+14yk2+yk14p_{k+1} - p_k = 3 + 2x_k + y_{k+1}^2 - y_{k+1} + \frac{1}{4} - y_k^2 + y_k - \frac{1}{4}
pk+1pk=3+2xk+yk+12yk+1yk2+ykp_{k+1} - p_k = 3 + 2x_k + y_{k+1}^2 - y_{k+1} - y_k^2 + y_k
pk+1pk=3+2xk+yk+12yk2yk+1ykp_{k+1} - p_k = 3 + 2x_k + y_{k+1}^2 - y_k^2 - y_{k+1} - y_k
pk+1=pk+3+2xk+yk+12yk2yk+1ykp_{k+1} = p_k + 3 + 2x_k + y_{k+1}^2 - y_k^2 - y_{k+1} - y_k
pk+1=pk+1+2xk+1+yk+12yk2yk+1ykp_{k+1} = p_k + 1 + 2x_k + 1 + y_{k+1}^2 - y_k^2 - y_{k+1} - y_k
其中yk+1y_{k+1}yky_k还是yk1y_k - 1取决去pk的符号p_k的符号

生成算法如下:

  1. 求初始误差, 将0,r0, r坐标带入p0=1+r122r2=54rp_0 = 1 + r - \frac{1}{2}^2 - r^2 = \frac{5}{4} - r
  2. 求下一个光栅点xk+1=xk+1x_{k+1} = x_k + 1
    如果pk<0p_k < 0, 则yk+1=yky_{k+1} = y_k
    否则选择为yk+1=yk1y_{k+1} = y_k - 1
  3. 绘制xk+1,yk+1x_{k+1}, y_{k+1},
  4. 计算差值Pk+1=Pk+1+2xk+1+yk+12yk2yk+1ykP_{k+1} = P_k + 1 + 2x_k + 1 + y_{k+1}^2 - y_k^2 - y_{k+1} - y_k,
    pk<0p_k<0Pk+1=pi+3+2xkP_{k+1} = p_i + 3 + 2x_k
    否则Pk+1=pi+1+2xkykP_{k+1} = p_i + 1 + 2x_k - y_k
  5. 如果x >= y 则终止循环否则执行2,3,4

代码实现

请参考中点画圆算法