使用什么算法来计算浮点半径的圆

What algorithm is used for computing a circle with floating point radius?

本文关键字:计算 什么 算法      更新时间:2023-10-16

中点圆算法非常适合计算半径为整数的圆。

void CircleOptimized(int xc, int yc, int r, int color) {
    unsigned int x= r, y= 0;//local coords     
    int          cd2= 0;    //current distance squared - radius squared
    if (!r) return; 
    drawpixel(xc-r, yc, color);
    drawpixel(xc+r, yc, color);
    drawpixel(xc, yc-r, color);
    drawpixel(xc, yc+r, color);
    while (x > y) {    //only formulate 1/8 of circle
        cd2-= (--x) - (++y);
        if (cd2 < 0) cd2+=x++;
        drawpixel(xc-x, yc-y, color);//upper left left
        drawpixel(xc-y, yc-x, color);//upper upper left
        drawpixel(xc+y, yc-x, color);//upper upper right
        drawpixel(xc+x, yc-y, color);//upper right right
        drawpixel(xc-x, yc+y, color);//lower left left
        drawpixel(xc-y, yc+x, color);//lower lower left
        drawpixel(xc+y, yc+x, color);//lower lower right
        drawpixel(xc+x, yc+y, color);//lower right right
     } 
}

例如,当传递r=1r=2时,输出分别如下所示:

.....  .XXX.
..X..  X...X
.X.X.  X...X
..X..  X...X
.....  .XXX.
 r=1    r=2

但是,我需要在r=1r=2之间再走几个步骤。也许(假设)r=1.33r=1.66可能看起来像这样:

.....  .....  ..X..  .XXX.
..X..  .XXX.  .X.X.  X...X
.X.X.  .X.X.  X...X  X...X
..X..  .XXX.  .X.X.  X...X
.....  .....  ..X..  .XXX.
r=1.0  r=1.3  r=1.6  r=2.0

但是,当我尝试调整上面的算法以使用浮点运算(有或没有舍入)时,它会失去对称性并生成不连续的路径(导致一些非常奇怪的形状)。

有没有更适合我目的的算法?

如果你只对简单的分数(如 4/3 和 5/3)感兴趣,我会过采样(即使用子像素,这里每个像素 9 个子像素,因此计算半径为 4 和 5 子像素的圆),然后从子像素推断出像素的良好值。 如果您推断出不是开、关,那么您正在执行抗锯齿。

基本圆图...

public void DrawCircle(float stepSize, float radius, int colour)
{
    float x, y;
    float angle;
    while (angle < 2*Math.PI)
    {
        x = radius * cos(angle);
        y = radius * sin(angle);
        // decide how to round your floating point X,Y here ...
        drawpixel(x,y,colour);
        angle += stepSize;
    }
}
我认为

泰勒近似可能有用

  • 使用一阶泰勒近似 (sqrt(u^2 + a) = u + a/2u) 计算 x^2= r^2- y^2 中的 x