加速度計を使用して特定の軸の変化を計算するOpenGLESでAndroidプロジェクトを作成しています。目的は、宇宙船のようなオブジェクトの移動ベクトルを回転させることです。問題は、回転行列の背後にある数学を理解できないことです。デフォルトの移動ベクトルは0,1,0で、+ yを意味するため、オブジェクトは最初は上向きに見えます。そして、私はその移動ベクトルを回転させて、それが指す場所にオブジェクトを移動できるようにしようとしています。電話で回転の変化を集めることができます。x軸:rotate [0]、y軸:rotate [1]、z軸:rotate[2]。回転行列を使用して移動ベクトルを回転させるにはどうすればよいですか?
2 に答える
ベクトルを回転させたい場合は、回転行列と呼ばれるものを作成する必要があります。
2Dでの回転
ベクトルまたは点をθだけ回転させたいとすると、三角法は新しい座標が
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平面で発生します)。3Dでは、Z軸を中心に回転すると
|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'|
注1:回転が行われる軸には、マトリックスに正弦要素または余弦要素がありません。
注2:この回転の方法は、教えるのが簡単で把握しやすいオイラー角回転システムに従います。これは、2Dおよび単純な3Dの場合に完全に機能します。ただし、3つの軸すべてを同時に回転させる必要がある場合は、ジンバルロックとして現れるこのシステムに固有の欠陥があるため、オイラー角が十分でない可能性があります。このような状況では、人々はQuaternionに頼ります。これは、これよりも高度ですが、正しく使用された場合、ジンバルロックの影響を受けません。
これで基本的なローテーションが明確になることを願っています。
回転ではなく回転
前述の行列は、半径rの円に沿って原点から距離r =√(x²+y²)でオブジェクトを回転させます。極座標を検索して理由を確認してください。この回転は、世界空間の起源、別名革命を基準にしています。通常、オブジェクトを、世界のつまりローカル原点の周りではなく、それ自体のフレーム/ピボットの周りで回転させる必要があります。これは、r = 0の特殊なケースと見なすこともできます。すべてのオブジェクトがワールド原点にあるわけではないため、これらのマトリックスを使用して回転するだけでは、オブジェクト自体のフレームを中心に回転するという望ましい結果は得られません。あなたは最初に翻訳します(移動)オブジェクトをワールド原点に移動し(オブジェクトの原点がワールドの原点と整列し、それによってr = 0になるように)、これらの行列の1つ(または複数)で回転を実行してから、元の位置に再度変換します。変換が適用される順序は重要です。複数の変換を組み合わせると、連結または合成と呼ばれます。
構成
コードで変換を試す前に、線形変換とアフィン変換、およびそれらの構成について読んで、1回のショットで複数の変換を実行することをお勧めします。その背後にある基本的な数学を理解していなければ、変換のデバッグは悪夢になります。この講義ビデオは非常に優れたリソースであることがわかりました。もう1つのリソースは、直感的であり、アニメーションでアイデアを説明することを目的とした変換に関するこのチュートリアルです(注意:私が作成しました!)。
任意のベクトルの周りの回転
投稿された質問のように、基本軸(X、Y、またはZ)を中心に回転するだけでよい場合は、前述の行列の積で十分です。ただし、多くの場合、任意の軸/ベクトルを中心に回転させたい場合があります。ロドリゲスの公式(別名軸角度公式)は、この問題に対して一般的に規定されている解決策です。ただし、ベクトルと行列だけで行き詰まっている場合にのみ、それに頼ってください。Quaternionを使用している場合は、必要なベクトルと角度でQuaternionを作成するだけです。クォータニオンは、3D回転を保存および操作するための優れた代替手段です。コンパクトで高速、たとえば軸角度表現で2つの回転を連結することはかなり高価で、行列では中程度ですが、クォータニオンでは安価です。通常、すべての回転操作はクォータニオンを使用して行われ、レンダリングパイプラインにアップロードするときに最後のステップとしてマトリックスに変換されます。クォータニオンに関する適切な入門書については、クォータニオンについてを参照してください。
ベクトルのX成分はM*cos(o)cos(t)+ x、Y成分はM cos(t)sin(o)+ y、z成分はM cos(o )* sin(t)+ zここで、Mはベクトルの大きさ、oは垂直面での回転角、tは水平面での回転角、xは回転中心のx値、yは回転中心のy値、zは回転中心のz値です。これでうまくいくかどうか教えてください。