绘制抗锯齿圆的算法?

问题描述 投票:0回答:4

绘制抗锯齿圆的好算法是什么? (已填充和未填充。)

algorithm drawing rendering graphics
4个回答
10
投票

Bresenham(因直线算法而闻名)也有圆算法。

吴晓林采用了直线算法进行抗锯齿,同样对圆算法进行了同样的处理。

http://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm

您可以通过此搜索找到圆算法:

http://www.google.com/search?q=Xiaolin%20Wu%20circle

-亚当


6
投票

如果您想要一个简单的方法,请从像素矩阵 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
投票

创建一个 Graphics 对象 g。 做

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

使用 g.FillEllipse 或 g.DrawEllipse 绘制抗锯齿圆

© www.soinside.com 2019 - 2024. All rights reserved.