重置旋转矩阵而不会丢失比例

时间:2012-07-10 19:39:34

标签: math opengl matrix rotation

我有一种情况需要一种方法将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

}

2 个答案:

答案 0 :(得分: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缩放因子。

答案 1 :(得分:0)

我认为没有任何矩阵魔法可以做到这一点,但你能将旋转和比例存储在不同的矩阵中吗?

void init() {
     _modelScale = some_scale_matrix;
}

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

    _model = _modelRot * _modelScale;
}

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