2

Java で 3D レンダラーを作成していますが、ソリッド カラーの塗りつぶしでポリゴンをレンダリングしようとすると問題が発生します。それは完全に正常に動作しますが、頻繁に引き裂かれますが、それがアルゴリズムが非効率的であるためなのか、それとも頂点だけが引き裂かれているために何か他のものなのかはわかりません。ここに写真があります:

例

ワイヤーフレーム: ここに画像の説明を入力 ポリゴンの頂点またはポイントの近くで引き裂かれていることがわかります。ピクセルの色を 2 次元配列に格納し、それを循環してレンダリングしています。ポリゴンを非常に小さくしても破れるので、パフォーマンスの問題ではないと思います。Bresham アルゴリズムを使用してピクセルを 2 次元配列に格納し、次にポリゴンでピクセルを取得して 1 つの大きな配列にし、ピクセルに到達するまで y を下ってから x を横切ります。それが beginLine として設定され、最後のものが endLine として設定されます。次に、ポイント間に線を引きます。

public void render()
{
    int tempPixels[][] = new int[(int) Math.max(vertex_1.getX(), Math.max(vertex_2.getX(), vertex_3.getX())) + 30][(int) Math.max(vertex_1.getY(), Math.max(vertex_2.getY(), vertex_3.getY())) + 30];

    for (int x = 0; x < vector_1.getWidth(); x++)
    {
        for (int y = 0; y < vector_1.getHeight(); y++)
        {
            if (vector_1.getPixels()[x][y] == 1)
            {
                tempPixels[(int) (x + Math.min(vertex_1.getX(), vertex_2.getX()))][(int) (y + Math.min(vertex_1.getY(), vertex_2.getY()))] = 1;
            }
        }
    }

    for (int x = 0; x < vector_2.getWidth(); x++)
    {
        for (int y = 0; y < vector_2.getHeight(); y++)
        {
            if (vector_2.getPixels()[x][y] == 1)
            {
                tempPixels[(int) (x + Math.min(vertex_2.getX(), vertex_3.getX()))][(int) (y + Math.min(vertex_2.getY(), vertex_3.getY()))] = 1;
            }
        }
    }

    for (int x = 0; x < vector_3.getWidth(); x++)
    {
        for (int y = 0; y < vector_3.getHeight(); y++)
        {
            if (vector_3.getPixels()[x][y] == 1)
            {
                tempPixels[(int) (x + Math.min(vertex_3.getX(), vertex_1.getX()))][(int) (y + Math.min(vertex_3.getY(), vertex_1.getY()))] = 1;
            }
        }
    }

    for (int y = 0; y < (int) Math.max(vertex_1.getY(), Math.max(vertex_2.getY(), vertex_3.getY())) + 4; y++)
    {
        int beginLine = -1;

        int endLine = -1;

        for (int x = 0; x < (int) Math.max(vertex_1.getX(), Math.max(vertex_2.getX(), vertex_3.getX())) + 4; x++)
        {
            if (tempPixels[x][y] == 1)
            {
                if (beginLine == -1)
                {
                    beginLine = x;
                }
                else
                {
                    endLine = x;
                }
            }
        }

        for (int i = beginLine; i < endLine; i++)
        {
            pixels[i][y] = 1;
            colors[i][y] = Color.PINK;
        }
    }

    vector_1.render();
    vector_2.render();
    vector_3.render();

    vertex_1.render();
    vertex_2.render();
    vertex_3.render();
}

したがって、基本的に私の質問は次のとおりです。このアルゴリズムは非効率的ですか?もしそうなら、より良い方法は何でしょうか? 頂点の近くで裂けているのはなぜですか?

4

2 に答える 2

1

問題の説明から、添付の画像があなたが望むものを示していないと結論付けることはできません。技術的には、ピンク色のゾーンは、「正しく」ペイントした三角形のセットを表すことができます (つまり、意図した通りに正確に) :p 更新として、イメージに含める予定の三角形をマークできます。三角形は 4 つあると思われますが、そのような組み合わせは他にもあります。

まず第一に、各 に対してyと を決定する部分が正しいようbeginLineに見えるので、関連付けられた垂直線分を描画するまで ( までではなく) までendLine反復する必要があります。endLineendLine-1

しかし、それはおそらく本当の問題ではありません。一度に 1 つの三角形を描いてみてください。一部の三角形がまだ正しくレンダリングされない場合は、最後の部分 (ベクトルと頂点をレンダリングする部分) を削除するとどうなるかを確認してみてください。これはなぜですか?実装を考慮すると、各 にセグメントのみが必要ですy。提供された画像は、実装が複数のセグメントをレンダリングする場合があることを示しています。したがって、ベクトルと頂点のレンダリングは正しくない可能性がありますが、複数の「完全に整列していない」三角形をレンダリングすることも原因となる可能性があります。

これでも解決しない場合は、三角形の間に小さなオフセットがある可能性があります。それがなぜなのか見てみてください。

効率に関連していますが、それは間違いではありません。一般に、効率と正確性はこのようには関係ありません。

編集

endLine = xの後に追加する必要がありbeginLine = xます。あなたの実装では、垂直線上に 1 つのピクセルしかない場合、それを描画しません ( endLine-1 のままになるため)。これは、この問題を修正する 1 つの方法です。また、beginLine描画を開始する前に が -1 より大きいことを確認してください。beginLineそして、から正確に反復することを忘れないでくださいendLine

于 2015-08-08T12:29:50.370 に答える