Bresenham的圆算法

时间:2011-10-01 05:26:25

标签: c

我有以下用于绘制圆圈的代码:

#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<math.h>

void main()
{
    int xc, yc, x, y, p[100], r, k;
    int gdriver=DETECT, gmode, errorcode;
    printf("\nEnter the center point(xc,yc): ");
    scanf("%d%d", &xc, &yc);
    printf("\nEnter the radius: ");
    scanf("%d", &r);
    printf("\nPlotting...\n");
    sleep(5);
    clrscr();

    initgraph(&gdriver, &gmode, "");
    p[0]=1-r;
    x=0;
    y=r;
    for(k=0;k<=y;k++)
    {
        putpixel(xc+x, yc+y, 9);
        putpixel(xc-x, yc-y, 9);
        putpixel(xc+x, yc-y, 9);
        putpixel(xc-x, yc+y, 9);
        putpixel(xc+y, yc+x, 9);
        putpixel(xc-y, yc-x, 9);
        putpixel(xc+y, yc-x, 9);
        putpixel(xc-y, yc+x, 9);

        if(p[k]>0)
        {
            p[k+1]= p[k]+ 2*(x+1)+1-2*(y+1);
            x++;
            y--;
        }
        else
        {
            p[k+1]=p[k]+2*(x+1)+1;
            x++;
        }
    }
        getch();
}

这部分代码:

putpixel(xc+x, yc+y, 9);
            putpixel(xc-x, yc-y, 9);
            putpixel(xc+x, yc-y, 9);
            putpixel(xc-x, yc+y, 9);
            putpixel(xc+y, yc+x, 9);
            putpixel(xc-y, yc-x, 9);
            putpixel(xc+y, yc-x, 9);
            putpixel(xc-y, yc+x, 9);

主要用于绘制相对于圆的点,并且由于圆的对称性而起作用。

但我无法弄清楚这部分代码到底在做什么;

if(p[k]>0)
        {
            p[k+1]= p[k]+ 2*(x+1)+1-2*(y+1);
            x++;
            y--;
        }
        else
        {
            p[k+1]=p[k]+2*(x+1)+1;
            x++;
        }

任何人都能解释一下它的功能吗? 提前谢谢。

2 个答案:

答案 0 :(得分:11)

更新公式看起来有点奇怪,我将给出我认为正确的步骤:

您从圆圈的最高点开始,顺时针旋转,直到角度达到45度。

现在,圆上的点大致满足(x ^ 2 + y ^ 2 = r ^ 2)。

这个想法是一次绘制一个像素,向正x方向移动。如果您发现下一个点(没有向下移动)离圆的中心太远,则应该将该点拉低一个单位。例如,如果查看像素化圆圈,您会发现它们基本上可以分解为一系列水平线和像素。水平线的每一端都标记出一条线,这条线的延伸距离圆圈太远,因此您会看到一个下降。

请注意,这里有一些关于您选择的点的自由裁量权。有3个圆形绘制学科:

  1. 内圈:选择点,使得在圆圈外不会绘制任何点(以便x^2 + y^2 < (r+1)^2 for each point r - 注意其r+1在此而不是r
  2. 外圈:选择点以便在圆圈内不会绘制任何点(以便x^2 + y^2 > (r-1)^2 for each point r - 请注意其r-1在此而不是r
  3. 中圈:选择最小化abs(x^2 + y^2 - r^2)的点。
  4. 您可以在算法中选择任何这些学科。除了代码块之外,这些方法是相同的(并且有很小的变化)。

    在每种情况下,您都必须计算每个点偏离圆的距离。这需要了解x^2 + (y-1)^2 - r^2。我们称之为序列p[k]。如果x^2 + (y-1)^2 - r^2 <= 0,则向下移动会显示该点太靠近圆心,因此下一个点应为(x+1, y)。在那种情况下,那么下一个偏差将是:

    p[k+1] = (x+1)^2 + (y-1)^2 - r^2 = x^2 + (y-1)^2 - r^2 + 2x + 1 = p[k] + 2*(x + 1) - 1
    

    如果x^2 + y^2 - r^2 > 0,则下一个点应为(x+1,y-1),以便

    p[k+1] = (x+1)^2 + (y-2)^2 - r^2 = x^2 + (y-1)^2 - r^2 + 2x + 1 - 2y + 3 = q[k] + 2*(x + 1) - 2*(y - 1) = p[k] + 2*(x+1) - 2 * (y + 1)
    

    这些公式根据您是否有兴趣找到外圆(像素永远不会太近),内圆(像素永远不会太远)或中心圆(大致在线)而改变,但这是必不可少的想法

答案 1 :(得分:-3)

你要问的程序部分是圆绘制算法的核心,它计算圆的一个八分圆的x,y坐标(八个putpixel()调用镜像这个八分圆到另外七个完成圆圈)。该算法详细解释了in this article