2

この記事を使用して、ブレゼンハムの線画をアンチエイリアスで実装しようとしています: 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;
        }
    }
}

何かが変わるかどうかはわかりませんが、すべての int を float に変更しました。float で除算が機能しているかどうかを確認するためです。とにかく整数の結果は同じです。

次に、呼び出しの例:

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

結果は次のようになります。 ここに画像の説明を入力

y0 + sy を y0 - sy に次のように変更すると:

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

出力は次のようになります。

ここに画像の説明を入力

x2 + sx を x2 - sx に変更すると、次のようになります。

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

出力は次のとおりです。

ここに画像の説明を入力

したがって、最後の構成は両方ともマイナスであり、次のようになります。

ここに画像の説明を入力

概ね良好ですが、若干の穴が開いています。だから、それはまだ間違っています。なぜ正しく描画されないのかわかりません。アンチエイリアシングなしで通常の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;
}

たぶん問題は、このためです。どうすればこれを修正できますか?
よろしく

4

1 に答える 1

1

このアルゴリズムは正しくないようです。

  • x0==x1またはy0==y1致命的なエラーです。
  • dx==dy致命的なエラーです。
  • ed=1whenの設定dx+dy=0は完全に任意です。
  • 2*e2==dyそして、2*e2==-dxステップごとに 3 ピクセルを描画します。

推奨事項: dx=dy、dx=-dy、dx=0、dy=0 を特別なケースとして扱い、オクタントごとに個別のケースを作成し、不要な場合は float を使用しないでください。

于 2015-06-16T15:50:17.280 に答える