在漂移绕Z轴的旋转 [英] Drift in rotation about z-axis

查看:419
本文介绍了在漂移绕Z轴的旋转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个应用程序,试图用旋转触摸一个对象,我注意到对象的位置漂移一段时间后(不应用任何转换!)。旋转大约只有z轴和完美的作品,但漂移后,只能转很少发生。

DS <大骨节病>将被用于翻译(使用上下键)。

_uNozzleCentreMatrix _ModelMatrixNozzle <大骨节病>将使用 DS 如果我纠正。

 私有静态最终浮动[] = _uNozzleCentre新的浮动[] {0.0,0.333605f,0.0,1.0F};
受保护的静态浮动[] = _uNozzleCentreMatrix新的浮动[4];公共无效onSurfaceChanged(GL10 GL,诠释的宽度,高度INT){
    gl.glViewport(0,0,宽度,高度);
    流通股比例=(浮点)宽/高;
    Matrix.setLookAtM(GLES20Renderer._ViewMatrix,0,0,0,1408米,0,0,0,0,1,0);
    Matrix.frustumM(GLES20Renderer._ProjectionMatrix,0,-ratio,比率,-1,1,2,8);
    Matrix.setIdentityM(GLES20Renderer._ModelMatrixNozzle,0);
}
私有静态无效的UpdateModel(INT UPDOWN,浮xAngle,浮yAngle,浮zAngle){
    // DS = GLES20Renderer._upDown - GLES20Renderer._lastUpDown;
    DS = 0; // DS使用按钮上下,但现在它是由0,所以按键上下也不会影响它的变化
    Matrix.multiplyMV(GLES20Renderer._uNozzleCentreMatrix,0,GLES20Renderer._ModelMatrixNozzle,0,GLES20Renderer._uNozzleCentre,0);
    如果(Math.abs(DS)大于0){
    }其他{
        如果(GLES20Renderer._zAngle&GT; = 360){
            GLES20Renderer._zAngle = GLES20Renderer._zAngle - 360;
        }
        如果(GLES20Renderer._zAngle&LT; = -360){
            GLES20Renderer._zAngle = GLES20Renderer._zAngle + 360;
        }
        Matrix.translateM(GLES20Renderer._ModelMatrixNozzle,0,GLES20Renderer._uNozzleCentreMatrix [0],GLES20Renderer._uNozzleCentreMatrix [1],0);
        Matrix.rotateM(GLES20Renderer._ModelMatrixNozzle,0,GLES20Renderer._zAngle,0,0,1);
        Matrix.rotateM(GLES20Renderer._ModelMatrixNozzle,0,-GLES20Renderer._lastZAngle,0,0,1);
        Matrix.translateM(GLES20Renderer._ModelMatrixNozzle,0,-GLES20Renderer._uNozzleCentreMatrix [0],-GLES20Renderer._uNozzleCentreMatrix [1],0);
    }
    Matrix.multiplyMM(GLES20Renderer._MVPMatrixNozzle,0,GLES20Renderer._ViewMatrix,0,GLES20Renderer._ModelMatrixNozzle,0);
    Matrix.multiplyMM(GLES20Renderer._MVPMatrixNozzle,0,GLES20Renderer._ProjectionMatrix,0,GLES20Renderer._MVPMatrixNozzle,0);    GLES20Renderer._lastZAngle = zAngle;
}

的.apk下载:

http://www.pixdip.com/opengles/rotation/rotation.apk

(试行刷卡极端更长的水平面积左至右观察漂移月初。请耐心等待!漂移可以为20秒发生)

有关那些人,这没有发生,这里是自动APK:
http://www.pixdip.com/opengles/rotation/automatic.apk

和code的编辑部分:

  Matrix.translateM(GLES20Renderer._ModelMatrixNozzle,0,GLES20Renderer._uNozzleCentreMatrix [0],GLES20Renderer._uNozzleCentreMatrix [1],0);
        Matrix.rotateM(GLES20Renderer._ModelMatrixNozzle,0,GLES20Renderer._zAngle,0,0,1);
        //Matrix.rotateM(GLES20Renderer._ModelMatrixNozzle,0,-GLES20Renderer._lastZAngle,0,0,1);
        Matrix.translateM(GLES20Renderer._ModelMatrixNozzle,0,-GLES20Renderer._uNozzleCentreMatrix [0],-GLES20Renderer._uNozzleCentreMatrix [1],0);


解决方案

有时浮点错误得到积累,因为矩阵堆栈的。

这可以通过使用单独的矩阵某些关键变换去除

 私有静态浮动[] = _TMatrix新的浮动[16];
私有静态浮动[] = _ModelMatrix新的浮动[16];
Matrix.setIdentity(Renderer._ModelMatrix);
Matrix.setIdentity(Renderer._TMatrix);
Matrix.translate(Renderer._ModelMatrix,xmov,ymov,0);
Matrix.translate(Renderer._TMatrix,-xmov,-ymov,0);
Matrix.multiply(Renderer._ModelMatrix,Renderer._TMatrix,Renderer._ModelMatrix);
//将导致身份模型矩阵,无需任何浮点错误

In an application, while trying to rotate an object using touch, I noticed drift in position of object after sometime (without any translation applied !!). The rotation is only about z-axis and works perfectly, but drift happens only after few rotations.

ds will be used for translation (using up-down button).

_uNozzleCentreMatrix and _ModelMatrixNozzle will use ds if I correct this.

private static final float[] _uNozzleCentre     = new float[]{0.0f, 0.333605f, 0.0f, 1.0f};
protected static float[] _uNozzleCentreMatrix   = new float[4];

public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);
    float ratio = (float) width / height;
    Matrix.setLookAtM(GLES20Renderer._ViewMatrix, 0, 0, 0, 7f, 0, 0, 0, 0, 1, 0);
    Matrix.frustumM(GLES20Renderer._ProjectionMatrix, 0, -ratio, ratio, -1, 1, 2, 8);
    Matrix.setIdentityM(GLES20Renderer._ModelMatrixNozzle, 0);
}
private static void updateModel(int upDown, float xAngle, float yAngle, float zAngle) {
    //ds                = GLES20Renderer._upDown - GLES20Renderer._lastUpDown;
    ds = 0; // ds changes with button up-down, but now it is made 0, so button up-down will not affect it
    Matrix.multiplyMV(GLES20Renderer._uNozzleCentreMatrix, 0, GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._uNozzleCentre, 0);
    if(Math.abs(ds) > 0) {
    } else {
        if(GLES20Renderer._zAngle >= 360) {
            GLES20Renderer._zAngle = GLES20Renderer._zAngle - 360;
        }
        if(GLES20Renderer._zAngle <= -360) {
            GLES20Renderer._zAngle = GLES20Renderer._zAngle + 360;
        }
        Matrix.translateM(GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._uNozzleCentreMatrix[0], GLES20Renderer._uNozzleCentreMatrix[1], 0);
        Matrix.rotateM(GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._zAngle, 0, 0, 1);
        Matrix.rotateM(GLES20Renderer._ModelMatrixNozzle, 0, -GLES20Renderer._lastZAngle, 0, 0, 1);
        Matrix.translateM(GLES20Renderer._ModelMatrixNozzle, 0, -GLES20Renderer._uNozzleCentreMatrix[0], -GLES20Renderer._uNozzleCentreMatrix[1], 0);
    }
    Matrix.multiplyMM(GLES20Renderer._MVPMatrixNozzle, 0, GLES20Renderer._ViewMatrix, 0, GLES20Renderer._ModelMatrixNozzle, 0);
    Matrix.multiplyMM(GLES20Renderer._MVPMatrixNozzle, 0, GLES20Renderer._ProjectionMatrix, 0, GLES20Renderer._MVPMatrixNozzle, 0);

    GLES20Renderer._lastZAngle = zAngle;
}

Apk for download:

http://www.pixdip.com/opengles/rotation/rotation.apk

(Try swiping a longer horizontal area from extreme left to right to observe drift early. Please be patient! Drift can take 20 seconds to occur)

For those whom it did not happen, here is the automated apk: http://www.pixdip.com/opengles/rotation/automatic.apk

and the edited part of code:

        Matrix.translateM(GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._uNozzleCentreMatrix[0], GLES20Renderer._uNozzleCentreMatrix[1], 0);
        Matrix.rotateM(GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._zAngle, 0, 0, 1);
        //Matrix.rotateM(GLES20Renderer._ModelMatrixNozzle, 0, -GLES20Renderer._lastZAngle, 0, 0, 1);
        Matrix.translateM(GLES20Renderer._ModelMatrixNozzle, 0, -GLES20Renderer._uNozzleCentreMatrix[0], -GLES20Renderer._uNozzleCentreMatrix[1], 0);

解决方案

Sometimes floating point errors get accumulated because of matrix stack.

This can be removed by using separate matrices for some critical transformations:

private static float[] _TMatrix = new float[16];
private static float[] _ModelMatrix = new float[16];
Matrix.setIdentity(Renderer._ModelMatrix);
Matrix.setIdentity(Renderer._TMatrix);
Matrix.translate(Renderer._ModelMatrix, xmov,ymov,0);
Matrix.translate(Renderer._TMatrix, -xmov,-ymov,0);
Matrix.multiply(Renderer._ModelMatrix, Renderer._TMatrix, Renderer._ModelMatrix);
// will result in an identity model matrix, without any floating point errors

这篇关于在漂移绕Z轴的旋转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆