2012-10-17 97 views
0

我不知道如何在考慮OpenGL中的樞軸位置的情況下使用四元數執行矩陣旋轉。目前我正在獲取的是圍繞某個點在空間中旋轉對象而不是這是我想要的地方樞紐。 下面是代碼[使用Java]基於四元數的旋轉和樞軸位置

四元數旋轉法:

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

    _rotation.x = xr; 
    _rotation.y = yr; 
    _rotation.z = 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; 
    acumQuat = Quaternion.mul(xrotQ, yrotQ); 
    acumQuat = Quaternion.mul(acumQuat, zrotQ); 



    Mat4 rotMat = Glm.matCast(acumQuat); 

    _model = new Mat4(1); 

    scaleTo(_scaleX, _scaleY, _scaleZ); 

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

    _model =rotMat.mul(_model);//_model.mul(rotMat); //rotMat.mul(_model); 

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


    translateTo(_x, _y, _z); 

    notifyTranformChange(); 
    } 

模型矩陣規模方法: 公共無效scaleTo(浮動的x,浮Y,浮動Z){

_model.set(0, x); 
    _model.set(5, y); 
    _model.set(10, z); 

    _scaleX = x; 
    _scaleY = y; 
    _scaleZ = z; 

    notifyTranformChange(); 
    } 

翻譯方法: public void translateTo(float x,float y,float z){

_x = x - _pivot.x; 
    _y = y - _pivot.y; 
    _z = z; 
    _position.x = _x; 
    _position.y = _y; 
    _position.z = _z; 

    _model.set(12, _x); 
    _model.set(13, _y); 
    _model.set(14, _z); 

    notifyTranformChange(); 
    } 

但這種方法中,我不使用四元正常工作:

public void rotate(Vec3 axis, float angleDegr) { 
    _rotation.add(axis.scale(angleDegr)); 
    // change to GLM: 
    Mat4 backTr = new Mat4(1.0f); 

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

    backTr = Glm.rotate(backTr, angleDegr, axis); 


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

    _model =_model.mul(backTr);///backTr.mul(_model); 
    notifyTranformChange(); 

    } 

回答

1

在我看來,你考慮到前和旋轉後的來回翻譯已經。爲什麼translateTo的最終調用?

此外,當您旋轉時,純旋轉總是圍繞原點。所以如果你想圍繞你的樞軸點旋轉。我會將您的樞軸點轉換爲原點,然後旋轉,然後轉回到樞軸點是正確的。因此,我期望你的代碼看起來像這樣:

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

_model =rotMat.mul(_model);//_model.mul(rotMat); //rotMat.mul(_model); 

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

,並沒有通話translateTo(_x, _y, _z);。另外,你能否確認旋轉部分已經做到了它應該做的?您可以通過比較rotMatGlm.rotate(new Mat4(1.0f), angleDegr, axis)來查看。他們應該是相同的輪換相同。

0

四元數描述旋轉。因此,你想如何繞一個樞軸點旋轉一些東西只有一個四元數?

您需要的最小值是一個R3矢量和一個四元數。只有一個轉換級別,你首先將物體轉過來然後移動到那裏。

如果您想要創建矩陣,請首先創建配給矩陣,然後添加未經修改的翻譯。

如果您只想調用glTranslate和glRotate(或glMultMatrix),您將首先調用glTranslate然後glRoatate。

編輯:

如果你不渲染,只是想知道每個頂點:

Vector3 newVertex = quat.transform(oldVertex) + translation; 
+0

我知道什麼Quaternion是什麼。我也不使用固定管道:) –

+0

但第一個建議解決了你的問題,對。或者按照我所說的計算一個變換矩陣,或者將四元數和平移應用到每個頂點。 – rioki