抗锯齿Bresenham的线路没有按预期工作

时间:2015-06-16 14:14:50

标签: c++ cocos2d-x bresenham

我尝试使用本文实现使用抗锯齿的bresenham线条绘图: http://members.chello.at/~easyfilter/bresenham.html

以下是功能:

void ColoringScene::drawLineAA(int x0, int y0, int x1, int y1, int r, int g, int b, int a)
{
    float dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
    float dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
    float err = dx-dy, e2, x2;                       /* error value e_xy */
    float ed = dx+dy == 0 ? 1 : sqrt((float)dx*dx+(float)dy*dy);

    for (;;){                                         /* pixel loop */
        setPixel(x0, y0, r, g, b, a*abs(err-dx+dy)/ed);
        e2 = err; x2 = x0;
        if (2*e2 >= -dx) {                                    /* x step */
            if (x0 == x1) break;
            if (e2+dy < ed) setPixel(x0, y0 + sy, r, g, b, a*(e2+dy)/ed);
            err -= dy; x0 += sx;
        }
        if (2*e2 <= dy) {                                     /* y step */
            if (y0 == y1) break;
            if (dx-e2 < ed) setPixel(x2 + sx, y0, r, g, b, a*(dx-e2)/ed);
            err += dx; y0 += sy;
        }
    }
}

不知道它是否会改变任何东西,但我把所有的东西都改成了漂浮物。只是为了确保分割是否适用于花车。无论如何整数结果是一样的。

现在,示例电话:

drawLineAA(10, 10, 50, 400, 255, 0, 0, 255);
drawLineAA(100, 10, 500, 40, 255, 0, 0, 255);

结果如下: enter image description here

如果我将y0 + sy更改为y0 - sy就像这样:

if (e2+dy < ed) setPixel(x0, y0 - sy, r, g, b, a*(e2+dy)/ed);

输出变为:

enter image description here

如果我将x2 + sx更改为x2 - sx,请执行以下操作:

if (dx-e2 < ed) setPixel(x2 - sx, y0, r, g, b, a*(dx-e2)/ed);

现在输出是:

enter image description here

所以最后的配置都是否定的,这给出了:

enter image description here

几乎不错,但出现了一些漏洞。所以它仍然是错的。我无法弄明白,为什么它没有正确绘制。当我尝试普通的bresenham没有抗锯齿时,它没有任何问题。

同样重要的是,在我的情况下,我使用cocos2d-x纹理,所以y被翻转。这就是我采用这种方法的原因:

void ColoringScene::setPixel(int x, int y, int r, int g, int b, int a){
    if(x < 0 || x >= img->getWidth() || y < 0 || y >= img->getHeight()) return;
    int index = (x + (img->getHeight() - y - 1) * img->getWidth()) * 4;
    data[index] = r;
    data[index + 1] = g;
    data[index + 2] = b;
    data[index + 3] = a;
}

也许问题是,因为这个。我该如何解决这个问题? 此致

1 个答案:

答案 0 :(得分:1)

此算法似乎不正确。

  • x0==x1y0==y1是致命错误。
  • dx==dy是致命错误。
  • ed=1完全任意时设置dx+dy=0
  • 2*e2==dy2*e2==-dx会导致每步绘制三个像素。

建议:将dx = dy,dx = -dy,dx = 0,dy = 0视为特殊情况,为每个八分圆制作单独的案例,如果您不需要,请不要使用浮点数。