4

2D カメラのモデル ビュー マトリックスを計算しようとしていますが、式を正しく取得できません。行列が OpenGL と互換性があるように、Affine3f 変換クラスを使用します。これは、私が試行錯誤して得たものに最も近いものです。このコードはカメラの回転とスケーリングを正常に行いますが、平行移動と回転を同時に適用すると、カメラの動きがおかしくなり、カメラが回転した形で動きます。(これはおそらく、最初に回転行列を適用してから変換したためです)

Eigen::Affine3f modelview;
modelview.setIdentity();
modelview.translate(Eigen::Vector3f(camera_offset_x, camera_offset_y, 0.0f));
modelview.scale(Eigen::Vector3f(camera_zoom_x, camera_zoom_y, 0.0f));
modelview.rotate(Eigen::AngleAxisf(camera_angle, Eigen::Vector3f::UnitZ()));
modelview.translate(Eigen::Vector3f(camera_x, camera_y, 0.0f));
[loadmatrix_to_gl]

私が欲しいのは、カメラがスクリーンスペースのオフセット位置を中心に回転およびスケーリングし、{(0,0) はこの場合はスクリーンの中央です}、ワールドスペースのグローバル xy 軸に沿って配置されることです {(0,0) も最初は画面の中央} から最終的な位置まで。どうすればいいですか?

この問題に影響を与える可能性のある正投影行列も設定したことに注意してください。

4

2 に答える 2

1

OpenGL を使用して XY 平面でレンダリングされた 2D 画像が必要な場合は、(1)Pを中心に反時計回りに回転し(2) Sでスケーリングし、(3) Cのピクセルが(新しくスケーリングおよび回転された画像) が原点にある場合、次の変換を使用します。

  1. -Pで平行移動 (これにより、 Pのピクセルが原点に移動します)
  2. 回転する
  3. Pで変換します (これにより、原点が元の場所に戻ります)
  4. Sでスケールし ます (以前にこれを行った場合、回転が台無しになります)
  5. -Cで翻訳

2D 画像が原点でレンダリングされている場合、それを見ることができるように負の z 軸に沿ってある値だけ移動して終了する必要もあります。

通常、これは OpenGL の基本 ( glTranslatefglScalefglRotatefなど) で行うだけです。そして、あなたは私がそれらをリストした逆の順序でそれらを行うでしょう. を使いたいのでglLoadMatrix、Eigen で説明した順序で処理を行います。OpenGL は列主行列を想定していることを覚えておくことが重要です (ただし、これは Eigen のデフォルトのようです。おそらく問題にはなりません)。

于 2012-05-18T18:21:25.897 に答える
0

JCooper は、初期行列を作成する手順をうまく説明してくれました。

しかし、私は最終的に問題を少し違った方法で解決しました。当時の私にとって明らかではなかったいくつかの追加事項や手順がありました。JCooper の回答のコメントを参照してください。1 つ目は、すべての行列演算が相対であることを認識することです。

したがって、絶対 xy 軸を使用してカメラを配置または移動する場合は、最初に行列を分解して、変更されていない軸でその絶対位置を抽出する必要があります。次に、古い位置と新しい位置の差によって行列を変換します。

Eigenでこれを行う方法は次のとおりです。

最初に Affine2f 行列cmatスカラー行列式 D を計算します。Eigen を使用すると、これは で行われD = cmat.linear().determinant();ます。matrev次に、D を使用して、現在の回転 + スケール行列 R の「逆」行列を計算します。matrev = (RS.array() / (1.0f / determ)).matrix());ここで、RS は次の式で与えられます。ここでcmat.matrix().topLeftCorner(2,2) 、カメラの絶対位置 P は次の式で与えられます。P = invmat * -Ccmat.matrix().col(2).head<2>()

ここで、カメラを絶対軸に沿ってどこにでも再配置し、回転とスケーリングを同じに保つことができます: V = RS * (T - P) ここで、RS は以前と同じで、T は新しい位置 vec で、P は分解された位置 vec です。次にcmat、カメラを移動するために V によって単純に変換されます。cmat.pretranslate(V)

于 2016-11-19T18:58:16.470 に答える