0

XNA を使い始めて、次のように for ループでフィールド (M11、M21 など) にアクセスしようとしています。

for (int x = 0; x < 4; x++) {
for (int y = 0; y < 4; y++)
  {
    // Can't use array notation with this struct. Doesn't work.
    matrix[x][y]     

    // Similar to above, but like a 2D array. Doesn't work either.
    matrix[x, y]     

    // ERROR - I'm using a variable like a method. Doesn't work. 
    matrix(x, y)     
  }
}

ですから、この後は自暴自棄になることは承知していますが、XNA マトリックスの個々のフィールドにアクセスして、for ループでループする方法を教えてください。C++ でこれができるのに、なぜ C# でできないのでしょうか?

これは、Frank Luna による「DirectX 11 を使用した 3D ゲーム プログラミング」のマトリックスの章の例であり、マトリックスについて詳しく知りたいので、この省略形を実行できるようにしたいと思います。とりあえずM11~M44まで全部書きます。

4

1 に答える 1

1

他の人がすでに指摘しているように、座標によってマトリックスのフィールドにアクセスする組み込みの方法はありません。不自然なシナリオでは頻繁に行う必要はなく、フィールドに直接アクセスする方が理論的には高速です (フレームワークのマトリックス コードは、この種のマイクロ最適化が重要になる場所のようなものです)。

とはいえ、この動作を有効にするためにコードを書くことに必死だった場合、おそらく次のようになります。

public static class MatrixUtil
{
    public static void Set(ref Matrix m, Int32 row, Int32 col, Single value)
    {
        if (row < 1 || row > 4) throw new ArgumentOutOfRangeException("row");
        if (col < 1 || col > 4) throw new ArgumentOutOfRangeException("col");

        switch ((row * 10) + col)
        {
            case 11: m.M11 = value; break;
            case 12: m.M12 = value; break;
            case 13: m.M13 = value; break;
            case 14: m.M14 = value; break;
            case 21: m.M21 = value; break;
            case 22: m.M22 = value; break;
            case 23: m.M23 = value; break;
            case 24: m.M24 = value; break;
            case 31: m.M31 = value; break;
            case 32: m.M32 = value; break;
            case 33: m.M33 = value; break;
            case 34: m.M34 = value; break;
            case 41: m.M41 = value; break;
            case 42: m.M42 = value; break;
            case 43: m.M43 = value; break;
            case 44: m.M44 = value; break;
        }
    }

    public static Single Get(ref Matrix m, Int32 row, Int32 col)
    {
        if (row < 1 || row > 4) throw new ArgumentOutOfRangeException("row");
        if (col < 1 || col > 4) throw new ArgumentOutOfRangeException("col");

        switch ((row * 10) + col)
        {
            case 11: return m.M11;
            case 12: return m.M12;
            case 13: return m.M13;
            case 14: return m.M14;
            case 21: return m.M21;
            case 22: return m.M22;
            case 23: return m.M23;
            case 24: return m.M24;
            case 31: return m.M31;
            case 32: return m.M32;
            case 33: return m.M33;
            case 34: return m.M34;
            case 41: return m.M41;
            case 42: return m.M42;
            case 43: return m.M43;
            case 44: return m.M44;
        }

        throw new InvalidOperationException();
    }
}

次に、次のように呼び出すことができます。

var m = Matrix.Identity;
for (int row = 1; row <= 4; row++)
{
    for (int col = 1; col <= 4; col++)
    {
        Console.WriteLine(MatrixUtil.Get(ref m, row, col));
    }
}

これが役立つと思う具体的なことはありますか?

于 2013-09-06T18:38:58.593 に答える