ベクトルであるゲームパッドのサムスティックの入力があります。ベクトルの値の範囲は、-1、-1 から +1、+1 にまたがる長方形内の円を定義します。
ベクトルが 8 つの可能な方向のどれに近いかを知りたいです。ベクトルが (0, 0) の場合は別に扱いますので気にしないでください。これどうやってするの?
注: これはゲーム用であるため、この関数は非常に頻繁に実行されます。たとえば、内積と三角関数を使用してベクトルと各方向ベクトルの間の角度を計算できることはわかっていますが、正確な角度。
ベクトルであるゲームパッドのサムスティックの入力があります。ベクトルの値の範囲は、-1、-1 から +1、+1 にまたがる長方形内の円を定義します。
ベクトルが 8 つの可能な方向のどれに近いかを知りたいです。ベクトルが (0, 0) の場合は別に扱いますので気にしないでください。これどうやってするの?
注: これはゲーム用であるため、この関数は非常に頻繁に実行されます。たとえば、内積と三角関数を使用してベクトルと各方向ベクトルの間の角度を計算できることはわかっていますが、正確な角度。
-1..1 の正方形の内側に、スティックの位置 (X) がいずれかの辺にある正方形を想像してください。
+-----------------+ +-----------------+
| | | |
| | | |
| X | | +-----X-+ |
| | | | | |
| O | | | O | |
| | | | | |
| | | +-------+ |
| | | |
| | | |
+-----------------+ +-----------------+
座標がどちら側にあるかを調べて、それが辺の中央に近いか、角に近いかを確認するだけです。内側の正方形が小さすぎる場合は、スティックが中央にあると見なすことができます。
何かのようなもの:
Public enum Direction {
None,
LeftUp, Up, RightUp, Right, RightDown, Down, LeftDown, Left
}
public Direction GetDirection(double x, double y) {
double absX = Math.Abs(x);
double absY = Math.Abs(y);
if (absX < 0.1 && absY < 0.1) {
// close to center
return Direction.None;
}
if (absX > absY) {
// vertical side
double half = absX * 0.4142;
if (x > 0) {
// left side
if (y > half) return Direction.LeftDown;
if (y < -half) return Diretion.LeftUp;
return Direction.Left;
} else {
// right side
if (y > half) return Direction.RightDown;
if (y < -half) return Direction.RightUp;
return Direction.Right;
}
} else {
// horisontal side
double half = absY * 0.4142;
if (y > 0) {
// bottom
if (x > half) return Direction.RightDown;
if (x < -half) return Direction.LeftDown;
return Direction.Down;
} else {
// top
if (x > half) return Direction.RightUp;
if (x < -half) return Direction.LeftUp;
return Direction.Up;
}
}
}
三角法はなく、単純な比較だけなので、かなり高速になるはずです。:)
(三角法を使用して、tan(22.5)であるポイント0.4142、または角度が45/2である側の位置を計算しました。)
sin a / cos a = tan a、
そしてあなたは持っています
Y = サイン a
X = cos a
したがって、逆正接関数を Y/X に適用すると、角度が得られます。
編集: 完全な円には、同じタンジェント値 (a
とa
+ pi
) を持つ 2 つの角度があります。X と Y の符号を使用して、どちらが有効かを判断します。
事前に作成された tan^-1 の近似テーブルを使用できます。入力ベクトルのサイズに基づいて角度を計算するのは非常に高速である必要があり、おそらくテーブルに非常に大きな解像度は必要ありません (実際、8 つの個別の方向のみが必要な場合は、テーブルに 8 つのエントリで十分です) )。