C中点圆算法将圆圈分成4

时间:2017-10-27 04:36:16

标签: c algorithm math geometry trigonometry

在我的程序中,我正在使用带有以下代码的中点圆算法渲染圆圈。

void drawcircle(int x0, int y0, int radius)
{
    int x = radius-1;
    int y = 0;
    int dx = 1;
    int dy = 1;
    int err = dx - (radius << 1);

    while (x >= y)
    {
        putpixel(x0 + x, y0 + y);
        putpixel(x0 + y, y0 + x);
        putpixel(x0 - y, y0 + x);
        putpixel(x0 - x, y0 + y);
        putpixel(x0 - x, y0 - y);
        putpixel(x0 - y, y0 - x);
        putpixel(x0 + y, y0 - x);
        putpixel(x0 + x, y0 - y);

        if (err <= 0)
        {
            y++;
            err += dy;
            dy += 2;
        }
        if (err > 0)
        {
            x--;
            dx += 2;
            err += (-radius << 1) + dx;
        }
    }
}

但我的问题是,是否可以让此功能以相同的方式工作,但将圆圈分成4个单独的部分?即,不是渲染正常的圆圈,它看起来有点像这样

enter image description here

1 个答案:

答案 0 :(得分:0)

在圆圈中放置

你实现了8个子部分相遇的重叠像素。圆圈的直径也是错误的(应该始终是因为半径* 2),这是一些重叠的原因。

要固定大小并删除重叠,我将圆圈的一半移出(向右下方)一个像素,并防止渲染最后一个迭代像素的一半。

此时不需要语句if(err <= 0),因为此时err将始终满足该条件。 y偏移每次迭代增加1个像素,err将在x需要步进时找到。

简易解决方案

通过这个解决你的问题关于在圆圈中放置洞。您只需要一个计数器来倒数您想要跳过的像素数。虽然该计数器是> 0不绘制任何像素。

我将其作为第4个参数hole添加到下面的代码段中。一个int,是圆圈顶部,底部,左侧和右侧孔洞尺寸的一半。

因此,如果你想要一个20像素的洞,那么最后一个参数是10。

见右下图。

限制和极客的东西

请注意,如果您将洞的最大尺寸设为更大,则不会绘制像素。sin(PI / 4) * radius作为旁注,绘制的像素数(没有孔)约为sin(PI / 4) * radius * 8 - 4,几乎比圆周小10%。

答案解决方案

void drawcircle(int x0, int y0, int radius, int hole) {
    int x = radius-1;
    int y = 0;
    int dx = 1;
    int dy = 1;
    int err = dx - (radius << 1);
    int x1 = x0 + 1;
    int y1 = x0 + 1;

    while (x >= y) {
        if(hole == 0){
            putpixel(x1 + x, y1 + y);
            putpixel(x0 - x, y0 - y);
            putpixel(x0 - y, y1 + x);
            putpixel(x1 + x, y0 - y);
            if (x > y) {
                putpixel(x1 + y, y1 + x);                
                putpixel(x0 - x, y1 + y);                
                putpixel(x0 - y, y0 - x);
                putpixel(x1 + y, y0 - x);
            }
        } else {
            hole--;
        }

        y++;
        err += dy;
        dy += 2;

        if (err > 0) {
            x--;
            dx += 2;
            err += (-radius << 1) + dx;
        }
    }
}

此外,我对这个功能非常了解,因为它制作了一些优秀的高性能形状,如圆形十字架和盒子,只有很小的变化,我认为值得分享。见图片

获得其他形状......

添加y err测试,然后将delta X和delta y错误更改更改为2以外的值。

        if(err <= 0){  // needed
            y++;
            err += dy;
            dy += 8;  << change this
        }

        if (err > 0) {
            x--;
            dx += 8;  << change this
            err += (-radius << 1) + dx;
        }
        // See image in answer
        // 8 made bottom right cross, 
        // 18 top right
        // 28 top left
        // 0.8 bottom left

enter image description here

图像显示了孔的形状和结果