18

3D で回転できるようにしたい 3D オブジェクトがあります。最も簡単な方法は、X と Y のマウスの動きを Y 軸と X 軸を中心とした回転に直接変換することですが、両方の軸に沿った回転がある場合、モデルの回転方法は直感に反するものになります (つまり、オブジェクトを 180 度回転させた場合)。軸に沿った動きは逆になります)。

上記の方法を簡単に実行できますが、2 つの軸を中心に回転する量を格納する代わりに、完全な回転行列を格納し、マウスのドラッグごとに同じ軸に沿ってさらに回転させることができますが、それがすぐに精度の問題が発生します。

4

4 に答える 4

7

現在のドラッグ方向に垂直な軸を中心にオブジェクトを回転させるのがおそらく最も直感的です。これは、マウスの動きごとに段階的に、またはドラッグの開始位置に対して相対的に行われます。2 つのオプションは、それぞれに長所と短所がある、わずかに異なるユーザー インタラクションを提供します。

角度と回転する軸を表す 3 次元ベクトルを回転行列に変換する比較的簡単な方法があります。

増分回転によ​​って生の回転行列を更新すると、行列が純粋な回転行列ではなくなるという点で、あなたは正しいです。これは、3x3 回転行列には、回転を表すために必要なデータの 3 倍のデータがあるためです。

回転を表すよりコンパクトな方法は、オイラー角を使用することで、最小の 3 つの値のベクトルを持ちます。現在の回転をオイラー角ベクトルとして取得し、それをマトリックスに変換し、回転を (インクリメンタルまたはその他の方法で) 適用し、マトリックスをオイラー角ベクトルに戻すことができます。その最後のステップは、行列の非回転成分を自然に排除するため、次の状態の純粋な回転行列が再び得られます。

オイラー角は概念的には優れていますが、前後の変換を行うのは大変な作業です。

より実用的な選択肢は、4 つの要素ベクトルであるクォータニオン(も) です。4 つの要素は回転と均一なスケールを指定します。ベクトルを単位長に正規化すると、スケール係数が 1.0 になります。角度軸の値も、非常に簡単に四元数の値に変換できることがわかります。

q.x = sin(0.5*angle) * axis.x;
q.y = sin(0.5*angle) * axis.y;
q.z = sin(0.5*angle) * axis.z;
q.w = cos(0.5*angle);

次に、現在の回転クォータニオンと増分回転クォータニオンのクォータニオン積 (単純な乗算と加算のみを使用) を取得して、両方の回転の実行を表す新しいクォータニオンを取得できます。その時点で、長さを正規化して純粋な回転を確保できますが、それ以外の場合は回転を組み合わせて繰り返し続けます。

従来のグラフィックス API を使用して回転した状態でモデルを表示する場合、クォータニオンを回転行列に変換するのは非常に簡単です (乗算と加算のみを使用します)。

于 2008-09-20T07:26:40.887 に答える
6

私のコンピュータ グラフィックス コースでは、車輪の再発明を避けることができる次のコードが与えられました。

trackball.h

trackball.c

于 2008-09-20T08:37:17.550 に答える
4

アキュムレータ行列を作成し、IDで初期化します。

各フレームは、オブジェクトを描画する前に、それをモデルビュー/ワールドマトリックスの状態に適用します。

マウスが動いたら、sensitive_constant*delta_xを使用してX軸を中心に回転行列を作成します。他のコンポーネントのY軸を中心に別の回転行列を作成します。1つを乗算し、次にもう1つをアキュムレータに乗算します。

マウスを動かすと、アキュムレータが変化します。描画するとき、それはあなたが期待するようにオブジェクトを方向付けます。

また、クォータニオンについて話している人は正しいです。これは、小さな増分変更の場合にのみ見栄えがします。対角線上ですばやくドラッグすると、期待どおりに回転しません。

于 2008-09-20T06:48:11.697 に答える
3

3つの行のそれぞれが再び垂直になるように回転行列を再正規化することで、精度の低下に対処できます。または、オブジェクトに関する既存の情報に基づいて、変更しようとしている回転行列を再生成できます。これにより、再正規化の必要がなくなります。

または、回転を処理するためのオイラー角の代わりとなるクォータニオンを使用することもできます。

私は初期の頃、このよくある質問から多くのことを学びました。このよくある質問では、オイラーの公式でこの問題を扱っています(ただし、別のアプリケーションの場合)。

于 2008-09-20T06:50:36.090 に答える