绘制抗锯齿圆形的算法?

16

有哪些适合绘制反锯齿圆形的好算法?(填充和未填充)

4个回答

10

1
实际上,众所周知的“Bresenham圆算法”并不是Bresenham自己的作品。 http://en.wikipedia.org/wiki/Midpoint_circle_algorithm 但是还是…… - Stewart

5
如果你想要简单的方法,可以从像素矩阵A到像素矩阵B进行柔化处理。
以下是我使用过的伪代码:
anti_alised_matrix[x][y] = point[x][y] / 2 + point[x+1][y]/8 + point[x-1][y]/8 + point[x][y-1]/8 + point[x][y+1]/8;

当然,这适用于灰度图像,但你也可以在RGB中轻松实现相同效果。

这真的非常简单,你还可以添加对角线,即[x+1][y+1],并将其分成16或32份。


0

为所有需要的人提供帮助。我刚刚为我的应用程序编写了一个圆形绘制器函数。

不幸的是,它只能绘制奇数直径的圆,但在 CPU 上绘制非常快。

此外,它可以轻松地移植到任何其他语言,因为没有使用特殊的语法/结构。

其主要优点是可以与混合一起工作,避免像素层叠(这会导致圆上出现黑斑)。

/*
* void drawPixel(int32_t x, int32_t y, uint32_t color)
*
* The algorithm's been written assuming this function to work with alpha-blending
* and packed RGBA colors, but you can change the color system easily.
* 
* AA - anti-aliasing 
*/

static inline void draw8Symmetry(int32_t cX, int32_t cY, int32_t x, int32_t y, int32_t color) {
    drawPixel(cX + x, cY + y, color);
    drawPixel(cX + x, cY - y, color);
    if (x != 0) {  // No repeating on top/bottom
        drawPixel(cX - x, cY + y, color);
        drawPixel(cX - x, cY - y, color);
    }
    if (x != y) { // No repeating on corners (45 deg)
        drawPixel(cX + y, cY + x, color);
        drawPixel(cX - y, cY + x, color);
        if (x != 0) { // No repeating on left/right sides
            drawPixel(cX + y, cY - x, color);
            drawPixel(cX - y, cY - x, color);
        }
    }
}

void drawCircle(int32_t cX, int32_t cY, int32_t r, uint32_t color) {
    int32_t i = 0;
    int32_t j = r + 1;
    int32_t rr = r * r;

    double lastFadeAmount = 0;
    double fadeAmount = 0;
    int32_t fadeAmountI;

    const int32_t maxOpaque = color >> 24;
    const int32_t noAlphaColor = color & 0x00FFFFFF;

    while (i < j) {
        double height = sqrt(rr - i * i);
        fadeAmount = (double)maxOpaque * (1.0 - (ceil(height) - height));

        // If fade amount is dropping, then, obviously, it's a new step
        if (fadeAmount > lastFadeAmount)
            j--;
        lastFadeAmount = fadeAmount;
        
        // Draw the semi-transparent circle around the filling
        draw8Symmetry(cX, cY, i, j, noAlphaColor | ((int32_t)fadeAmount << 24));

        // Draw central filling
        if (i != 0)
            for (int32_t x = -j + 1; x < j; x++) {
                drawPixel(cX + x, cY + i, color);
                drawPixel(cX + x, cY - i, color);
            }
        else
            for (int32_t x = -j + 1; x < j; x++)
                drawPixel(cX + x, cY + i, color);

        i++;
    }

    // Draw top and bottom parts
    while (i < r) {
        int32_t lineLength = ceil(sqrt(rr - i * i));

        for (int32_t x = -lineLength + 1; x < lineLength; x++) {
            drawPixel(cX + x, cY + i, color);
            drawPixel(cX + x, cY - i, color);
        }

        i++;
    }
}

-11
创建一个名为g的图形对象。 执行

g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

使用 g.FillEllipse 或 g.DrawEllipse 绘制您的抗锯齿圆形。

1
他是否曾经说过他在使用.NET? - Tomalak
6
他要求的是一种算法,而不是针对某个特定平台的示例,演示如何使用一个可以为你完成操作的工具。 - OJ.
1
“如何使用自动化工具”听起来对我来说完全是“算法”的反义词。算法通常涉及数学,并且可以在任何地方工作,您只需将属性设置为预定义的值即可。;-) - Tomalak
呵呵,这些是有趣的注释。 :) (如果可以的话,我会选择简单的选项,但是...) - John Scamps
4
我实际上发现这个评论很有用,因为我确实需要知道如何在.NET中做到这一点。 - Guy
显示剩余4条评论

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