1

私はVector2とXNAを使用してきましたが、ゼロベクトルでNormalize()メンバー関数を呼び出すと、{NaN、NaN}のベクトルに正規化されることがわかりました。これはすべてうまくいっていますが、私の場合は、代わりにゼロベクトルのままにしておくことをお勧めします。

このコードをプロジェクトに追加すると、かわいい拡張メソッドが有効になります。

using ExtensionMethods;

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static Vector2 NormalizeOrZero(this Vector2 v2)
        {
            if (v2 != Vector2.Zero)
                v2.Normalize();
            return v2;
        }
    }
}

残念ながら、このメソッドは、この拡張メソッドを呼び出すために使用するベクトルを単純に正規化するのではなく、正規化されたベクトルを返します。代わりに、 vector2Instance .Normalize()のように動作させたいと思います。

これを無効にする以外に、「v2」が変更されるようにこれを調整するにはどうすればよいですか?(基本的に、「this」オブジェクトにアクセスする必要があります。または、「v2」を参照して渡す必要があります。)

編集:

そして、はい、私はこれを試しました:

    public static void NormalizeOrZero(this Vector2 v2)
    {
        if (v2 != Vector2.Zero)
            v2.Normalize();
    }

動作しません。v2はNormalizeOrZeroのスコープ内の単なる変数です。

4

4 に答える 4

3

Vector 2は実際には構造体であるため、これは機能しません。これは、値によって渡され、呼び出し元のコピーを変更できないことを意味します。あなたができる最善のことは、lomaxxxによって指定された回避策だと思います。

これは、一般的に構造体の使用を避けるべき理由を示しています。詳細については、この質問を参照してください。Vector2は、構造体は不変である必要があるというガイドラインに違反していますが、XNAのコンテキストでそうすることはおそらく理にかなっています。

于 2008-11-20T01:40:31.957 に答える
1

さて、あなたが本当にこれをやりたくてたまらないのなら、あなたはこのようなことをすることができます:

public static void NormalizeOrZero(this Vector2 ignore, ref Vector2 v2)
{
    if (v2 != Vector2.Zero)
        v2.Normalize();
}

あなたはそれをこのように呼ぶでしょう:

v2.NormalizeOrZero(ref v2);

それは非常に醜いですが、それが価値があるもののために、それはうまくいくでしょう。ただし、その時点で、最初に静的メソッドを呼び出すこともできます。

于 2008-11-20T01:49:43.763 に答える
0

2番目のコードサンプルが機能しない理由はわかりませんが、最初のコードが目的どおりに機能する場合は、次の手順を実行するだけで回避できます。

Vector2 v2 = new Vector2()
v2 = v2.NormalizeOrZero();
于 2008-11-20T01:30:27.250 に答える
0

ref引数にと修飾子の両方が必要thisになりますが、これは機能しないようです。

于 2008-11-20T01:42:06.743 に答える