1

OpenGLのモデル行列を絶対値に回転させるメソッドが必要な場合があります。そこにあるほとんどのrotate()メソッドは、現在の行列に新しい回転を掛けて、現在のメソッドに回転を追加します。古い回転を維持せずに、モデル行列をある値に回転させる必要があります。私が現在していることは、現在のマトリックスを破壊してアイデンティティにすることです。次に、前に設定したスケール変数に基づいて、最初からスケールを計算します。次に、クォータニオンから取得した回転行列を乗算し、最終的には再度変換します。

そのようなタスクには計算が多すぎるように私には見えます。スケールと平行移動の部分をそのままにして、行列の回転をリセットするより短い方法はありますか?これが私の現在のメソッド(Java)です:

 public void rotateTo3( float xr,float yr,float zr) {



 Quaternion  xrotQ=   Glm.angleAxis( (xr),Vec3.X_AXIS);
 Quaternion  yrotQ=   Glm.angleAxis( (yr),Vec3.Y_AXIS);
 Quaternion  zrotQ=   Glm.angleAxis( (zr),Vec3.Z_AXIS);
  xrotQ= Glm.normalize(xrotQ);
  yrotQ= Glm.normalize(yrotQ);
  zrotQ= Glm.normalize(zrotQ);

  Quaternion acumQuat=new Quaternion();
  acumQuat= Quaternion.mul(xrotQ,yrotQ);
  acumQuat= Quaternion.mul(acumQuat,zrotQ);


  Mat4 rotMat=new Mat4(1);
  rotMat=Glm.matCast(acumQuat);

    _model = new Mat4(1);




   scaleTo(_scaleX, _scaleY, _scaleZ);//reconstruct scale
   _model = Glm.translate(_model, new Vec3(_pivot.x, _pivot.y, 0));


  _model=rotMat.mul(_model); ///add new rotation


   _model = Glm.translate(_model, new Vec3(-_pivot.x, -_pivot.y, 0));



   translateTo(_x, _y, _z);//reconstruct translation

}

4

2 に答える 2

6

これは実際にはかなり簡単に行われます。重要な洞察は、均質な変換行列が3つの部分で構成されていることです。左上の3×3行列は回転スケーリング、右上の1×3列は平行移動、左下の3×1はアフィンスケーリングを可能にし、右下は1です。

だから私たちはそれを次のように書くことができます

RS T
 A 1

ここで、特定のRSをRとSに分解します。これで、回転は常に直交します。つまり、R ^ T = R^-1になります。ただし、スケーリングはそうではありません。スケーリングについては、S ^ T = S!= S ^ -1であるため、次のように記述できます。

(RS)^T * RS = S^T * R^T * R * S = S^T * R^-1 * R * S = S^T * S = S^2

スケーリングは対角線上でのみ発生するため、対角線上の要素の平方根を取得することにより、x、y、およびzのスケーリング係数を抽出できます。

于 2012-07-10T22:19:53.413 に答える
0

これを行うためのマトリックスマジックはないと思いますが、回転とスケールを別々のマトリックスに保存できますか?

void init() {
     _modelScale = some_scale_matrix;
}

void update() {
    _modelRot = LoadIdentity();
    do_some_rotation(_modelRot)

    _model = _modelRot * _modelScale;
}

必要に応じて、これを翻訳用の 3 番目のマトリックスに拡張することもできます。

于 2012-07-10T20:12:04.140 に答える