web-dev-qa-db-ja.com

3D空間でのベクトルの回転

加速度計を使用して特定の軸の変化を計算するAndroidプロジェクトをopengl esで作成していますが、目的は宇宙船のようなオブジェクトの移動ベクトルを回転させることです。問題は、回転行列の背後にある数学を理解できないことです。デフォルトの移動ベクトルは0,1,0で、+ yを意味するため、オブジェクトは最初は上向きに見えます。そして、その移動ベクトルを回転させて、オブジェクトをポイントする場所に移動できるようにします。電話でローテーションの変更を収集できます。 x軸:回転[0]、y軸:回転[1]、z軸:回転[2]。回転行列を使用して移動ベクトルを回転するにはどうすればよいですか?

46
deniz

ベクトルを回転させる場合は、 回転行列 と呼ばれるものを作成する必要があります。

2Dでの回転

ベクトルまたはポイントをθだけ回転させたい場合、 trigonometry は新しい座標が

    x' = x cos θ − y sin θ
    y' = x sin θ + y cos θ

これをデモするために、基軸XとYを使用してみましょう。 X軸を反時計回りに90度回転させると、X軸がY軸に変換されます。検討する

    Unit vector along X axis = <1, 0>
    x' = 1 cos 90 − 0 sin 90 = 0
    y' = 1 sin 90 + 0 cos 90 = 1
    New coordinates of the vector, <x', y'> = <0, 1>  ⟹  Y-axis

これを理解すると、これを行うためのマトリックスの作成が簡単になります。マトリックスは、これを快適で一般化された方法で実行するための数学的なツールであり、1つの一般的な方法を使用して、回転、拡大縮小、平行移動(移動)などのさまざまな変換を1つのステップで組み合わせて実行できます。線形代数から、点またはベクトルを2Dで回転させるために、構築される行列は

    |cos θ   −sin θ| |x| = |x cos θ − y sin θ| = |x'|
    |sin θ    cos θ| |y|   |x sin θ + y cos θ|   |y'|

3Dでの回転

これは2Dで機能しますが、3Dでは3番目の軸を考慮するために取り入れる必要があります。 2Dで原点(点)を中心にベクトルを回転するとは、3DでZ軸(線)を中心にベクトルを回転することを意味します。 Z軸を中心に回転しているため、その座標は一定、つまり0°に保つ必要があります(回転は3DのXY平面で発生します) Z軸を中心に回転する3Dでは、

    |cos θ   −sin θ   0| |x|   |x cos θ − y sin θ|   |x'|
    |sin θ    cos θ   0| |y| = |x sin θ + y cos θ| = |y'|
    |  0       0      1| |z|   |        z        |   |z'|

y軸の周りは

    | cos θ    0   sin θ| |x|   | x cos θ + z sin θ|   |x'|
    |   0      1       0| |y| = |         y        | = |y'|
    |−sin θ    0   cos θ| |z|   |−x sin θ + z cos θ|   |z'|

x軸の周りは

    |1     0           0| |x|   |        x        |   |x'|
    |0   cos θ    −sin θ| |y| = |y cos θ − z sin θ| = |y'|
    |0   sin θ     cos θ| |z|   |y sin θ + z cos θ|   |z'|

:回転が行われる軸には、マトリックスに正弦要素または余弦要素がありません。これでローテーションのケースが明確になることを願っています。

構成

前述のマトリックスは、オブジェクトが原点から距離r =√(x²+y²)にあるかのようにオブジェクトを回転させます。ルックアップ 極座標 理由を知るため。この回転は、ワールド空間の原点を基準にします。通常、オブジェクトを世界の周りではなく、独自のフレーム/ピボットの周りで回転させる必要があります。すべてのオブジェクトがワールドの原点にあるわけではないため、これらのマトリックスを使用して回転しても、オブジェクトのフレームを中心に回転するという望ましい結果は得られません。したがって、 translation についても学ぶ必要があります。最初にオブジェクトをワールドの原点に移動(移動)し(オブジェクトの原点がワールドの原点と一致するようにして、r = 0にします)、これらの行列の1つ(または複数)で回転を実行してから、元に戻します以前の場所に。変換が適用される順序 matters

コード内の変換で遊ぶ前に、線形およびアフィン変換とその合成について読んで、1回のショットで複数の変換を実行することをお勧めします。その背後にある基本的な数学を理解しないと、変換のデバッグは悪夢になります。 この講義ビデオ は非常に優れたリソースであることがわかりました。もう1つのリソースは 変換に関するこのチュートリアル です。これは直感的で、アニメーションでアイデアを説明することを目的としています。

注:回転を実行するこの方法は、 オイラー角 回転システムに従います。これは、2Dおよび単純な3Dの場合に完全に機能します。しかし、3つすべての軸の周りで同時に回転を実行する必要がある場合、オイラー角は、 ジンバルロック として現れるこのシステムに固有の欠陥のため、これには十分ではありません。このような状況では、人々は Quaternion sに頼ります。これはこれよりも高度ですが、正しく使用するとジンバルロックの影響を受けません。

137
legends2k

こちらのリファレンスドキュメント: http://developer.Android.com/reference/Android/opengl/Matrix.html

  1. 回転行列を作成する
  2. 行列でベクトルを変換する

数学を理解する必要はありません。ライブラリ関数が仕事を完了します。

0
Minthos