web-dev-qa-db-ja.com

2Dユークリッドベクトル回転

座標(0, 1)にあるユークリッドベクトルaがあります。 aを原点を中心に90度(時計回り)回転させたい:(0, 0)

これがどのように機能するかを適切に理解している場合、回転後の結果の(x、y)座標は(1, 0)になります。代わりに45度(まだ時計回りに)回転させた場合、結果の座標は(0.707, 0.707)になるはずです。

theta = deg2rad(angle);

cs = cos(theta);
sn = sin(theta);

x = x * cs - y * sn;
y = x * sn + y * cs;

angle値が90.0度の上記のコードを使用すると、結果の座標は(-1, 1)になります。そして、私はとても混乱しています。以下のリンクにある例は、上記と同じ式を確実に表していますか?

私は何を間違えましたか?または、ベクトルの回転方法を誤解していませんか?

46

関数から変数を削除する必要があります。

x = x * cs - y * sn; // now x is something different than original vector x
y = x * sn + y * cs;

xが2行目に到達する前に計算されないように、新しい座標を作成します。

px = x * cs - y * sn; 
py = x * sn + y * cs;
70
Caspar Kleijne

ベクトルを90度回転させるのは特に簡単です。

(x, y)は90度回転した(0, 0)(-y, x)です。

時計回りに回転させたい場合は、逆の方法で(y, -x)を取得するだけです。

0,0を中心に90度回転します。

x' = -y
y' = x

Px、pyを中心に90度回転:

x' = -(y - py) + px
y' = (x - px) + py
19
Altivo

標準クラスの方が簡単に聞こえます:

std::complex<double> vecA(0,1);
std::complex<double> i(0,1); // 90 degrees
std::complex<double> r45(sqrt(2.0),sqrt(2.0));
vecA *= i;
vecA *= r45;

ベクトル回転は、複素乗算のサブセットです。

5
MSalters

新しい座標の「新しい」x部分に基づいて、新しい座標のy部分を計算しています。基本的に、これは新しい出力に関して新しい出力を計算することを意味します...

入力と出力の観点から書き直してみてください。

vector2<double> multiply( vector2<double> input, double cs, double sn ) {
  vector2<double> result;
  result.x = input.x * cs - input.y * sn;
  result.y = input.x * sn + input.y * cs;
  return result;
}

次に、これを行うことができます:

vector2<double> input(0,1);
vector2<double> transformed = multiply( input, cs, sn );

変数に適切な名前を選択すると、この問題をすべて回避できることに注意してください!

5
xtofl