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;
}

如果您愿意,也可以将其扩展到第三个矩阵进行翻译。

于 2012-07-10T20:12:04.140 回答