繁体   English   中英

Bresenham的圆算法

[英]Bresenham's circle algorithm

我有以下代码来绘制圆圈:

#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++;
        }

任何人都可以解释一下它的作用吗? 提前致谢。

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

您从圆圈的最高点开始,顺时针旋转直到角度达到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)abs(x^2 + y^2 - r^2)

您可以在算法中选择任何这些学科。 除了代码块之外,这些方法是相同的(并且其中的更改很小)。

在每种情况下,您都必须计算每个点偏离圆的距离。 这需要知道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)

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM