2012-01-27 7 views
2

私は単純なゲームで作業しており、ゲームの2D衝突反応の一部を単純化しようとしています。特定のオブジェクトが壁に当たったとき、私は衝突の法線(collisionPoint - objectCenter)を計算し、その法線に基づいて反射します。私はその法線ベクトルを最も近いに丸めることに興味がありますが、それについては良い方法があるかどうかはわかりません。2Dベクトルを最も近い15度に丸める方法

私の現在の考えは、これはそれを行うために合理的な方法です。この

float angle = atan2(normal.Y, normal.X) * Rad2Deg; 
float newAngle = ((int)(angle + 7.5f)/15) * 15.0f * Deg2Rad; 
vector2 newNormal = vector2(cos(newAngle), sin(newAngle)); 

ような何かをしているのですか?より良い方法がありますか?

+2

私の三角法のスキルは、これまでのものではありません...しかし、 –

+0

これは衝突応答の設計の一部であり、数学を簡略化するものではありません。 – chaosTechnician

+0

そのコードはおそらく私がやることでしょう。 – robbrit

答えて

2

これを試してみてください:

float roundAngle = 15 * Deg2Rad; 
float angle = (float)Math.Atan2(normal.Y, normal.X); 
Vector2 newNormal; 

if (angle % roundAngle != 0) 
{ 
    float newAngle = (float)Math.Round(angle/roundAngle) * roundAngle; 
    newNormal = new Vector2((float)Math.Cos(newAngle), (float)Math.Sin(newAngle)); 
} 
else 
{ 
    newNormal = Vector2.Normalize(normal); 
} 

あなたはこの例を取る、7.5を追加する必要はありません:あなたは最寄りの15度の角度をしたい場合

// 4 degrees should round to 0 
    (4 + 7.5)/15 == 11.5/15 == 0.77 
// When this gets rounded up to 1 and multiplied by 15 again, it becomes 15 degrees. 

// Don't add 7.5, and you get this: 
    4/15 == 0.27 
// When rounded, it becomes 0 and, as such the correct answer 

// Now how about a negative number; -12 
    -12/15 == -0.8 
// Again, when rounded we get the correct number 
+0

すでに存在する 'Math.Round()'関数を使って負の数値を扱うのは意味があります。ありがとう。 – chaosTechnician

0

は実際にこれは、より正確である: 行いますこれは:

newangle% = INT(((angle%+7.5)/15)*15) 

INTいつも、これは適切にneいずれにしてもポジティブまたはネガティブなアングルが楽しめます! あなたがradとradに次数を使う部分を必要に応じて必要に応じて追加します。括弧の中に書いてください(角度が度で与えられていない場合は角度%のすぐ隣にあり、そこにあるrad2degの乗数を使用します) あなたは基本的なやり方で、いくつかの修正を加えてこれを実行します。それはCコードなどでうまくいくでしょう。

+0

実際これはOPよりもあまり正確ではありません。 'int'へのキャストのポイントは、15を掛け合わせると15の倍数になります。ここでは基本的に大きな円を描き、' int + 'に' angle + 7.5 ' – annonymously

関連する問題