画填充圆形的快速算法?

54

我正在使用Bresenham圆算法来快速绘制圆形。但是,我也想(根据用户的请求)绘制填充的圆形。

是否有一种快速高效的方法来实现这一点?类似于Bresenham的方法?

我使用的语言是C语言。

14个回答

0

我做了与AlegGeorge相似的事情,但改变了三行。 我认为这样更快,但这些是results 我是否做错了什么? 我的函数名为DrawBruteforcePrecalcV4。 这是代码:

for (int x = 0; x < radius ; x++) // Instead of looping from -radius to radius I loop from 0 to radius
{
    int hh = (int)std::sqrt(radius_sqr - x * x);
    int rx = center_x + x;
    int cmx = center_x - x;
    int ph = center_y+hh;

    for (int y = center_y-hh; y < ph; y++)
    {
      canvas[rx][y] = 1;
      canvas[cmx][y] = 1;
    }
}

0
以下两种方法通过一次绘制多个圆的部分来避免重复的平方根计算,因此应该非常快速:
void circleFill(const size_t centerX, const size_t centerY, const size_t radius, color fill) {
    if (centerX < radius || centerY < radius || centerX + radius > width || centerY + radius > height) 
        return;

    const size_t signedRadius = radius * radius;
    for (size_t y = 0; y < radius; y++) {
        const size_t up = (centerY - y) * width;
        const size_t down = (centerY + y) * width;
        const size_t halfWidth = roundf(sqrtf(signedRadius - y * y));
        for (size_t x = 0; x < halfWidth; x++) {
            const size_t left = centerX - x;
            const size_t right = centerX + x;
            pixels[left + up] = fill;
            pixels[right + up] = fill;
            pixels[left + down] = fill;
            pixels[right + down] = fill;
        }
    }
}


void circleContour(const size_t centerX, const size_t centerY, const size_t radius, color stroke) {
    if (centerX < radius || centerY < radius || centerX + radius > width || centerY + radius > height) 
        return;
    
    const size_t signedRadius = radius * radius;
    const size_t maxSlopePoint = ceilf(radius * 0.707106781f); //ceilf(radius * cosf(TWO_PI/8));

    for (size_t i = 0; i < maxSlopePoint; i++) {
        const size_t depth = roundf(sqrtf(signedRadius - i * i));

        size_t left = centerX - depth;
        size_t right = centerX + depth;
        size_t up = (centerY - i) * width;
        size_t down = (centerY + i) * width;

        pixels[left + up] = stroke;
        pixels[right + up] = stroke;
        pixels[left + down] = stroke;
        pixels[right + down] = stroke;

        left = centerX - i;
        right = centerX + i;
        up = (centerY - depth) * width;
        down = (centerY + depth) * width;

        pixels[left + up] = stroke;
        pixels[right + up] = stroke;
        pixels[left + down] = stroke;
        pixels[right + down] = stroke;
    }
}

0

我会先生成一个点的列表,然后使用多边形绘制函数进行渲染。


2
如果他已经为开放版本实现了Bresenham算法,则他正在工作于比使用API更低层次的地方……无论是为了学习目的还是为了实现API。 - dmckee --- ex-moderator kitten

0

这可能不是您正在寻找的算法,也不是最高效的算法,
但我总是做类似于这样的事情:

void fillCircle(int x, int y, int radius){

   // fill a circle
   for(int rad = radius; rad >= 0; rad--){

      // stroke a circle
      for(double i = 0; i <= PI * 2; i+=0.01){

         int pX = x + rad * cos(i);
         int pY = y + rad * sin(i);

         drawPoint(pX, pY);

      }

   }

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接