【问题标题】:safeguard against floating point errors in java防止java中的浮点错误
【发布时间】:2012-08-25 09:52:30
【问题描述】:

随着游戏中渲染的帧数增加超过一定 限制,而不是为以下类型的矩阵变换获取单位矩阵:

Matrix.setIdentity(ModelMatrix);
Matrix.translate(ModelMatrix, xmov,ymov,0);
Matrix.translate(ModelMatrix, -xmov,-ymov,0);

有一些小值被添加到列中(因为 java 中的浮点错误),并在矩阵中逐渐变大(不再是单位)并导致奇怪的转换。下面是代码:

    ...// _ModelMatrixNozzle is set as identity matrix like all other 4x4 matrices in my app in onSurfaceChanged method
    ...// this code is part of update() method, called by onDrawFrame() in renderer thread
    GLES20Renderer._uNozzleCentreMatrix[0] = GLES20Renderer._ModelMatrixNozzle[0] * GLES20Renderer._uNozzleCentre[0] + GLES20Renderer._ModelMatrixNozzle[4] * GLES20Renderer._uNozzleCentre[1] + GLES20Renderer._ModelMatrixNozzle[8] * GLES20Renderer._uNozzleCentre[2] + GLES20Renderer._ModelMatrixNozzle[12] * GLES20Renderer._uNozzleCentre[3];
    GLES20Renderer._uNozzleCentreMatrix[1] = GLES20Renderer._ModelMatrixNozzle[1] * GLES20Renderer._uNozzleCentre[0] + GLES20Renderer._ModelMatrixNozzle[5] * GLES20Renderer._uNozzleCentre[1] + GLES20Renderer._ModelMatrixNozzle[9] * GLES20Renderer._uNozzleCentre[2] + GLES20Renderer._ModelMatrixNozzle[13] * GLES20Renderer._uNozzleCentre[3];
    GLES20Renderer._uNozzleCentreMatrix[2] = 0;
    GLES20Renderer._uNozzleCentreMatrix[3] = 1;
    if(Math.abs(ds) > 0) {
        /*transformations will be added here if the errors are solved*/
    } 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);
    }

下载apk:http://www.pixdip.com/opengles/rotation/floating.apk

虽然这不是必需的,但是完整的代码在这里:Drift in rotation about z-axis

【问题讨论】:

  • 您的文字发表了陈述,但没有提出问题。从标题中,我们可能会认为您希望避免因重复操作而漂移。但是您没有提供有助于回答您的问题的上下文。翻译和它的逆必须是恒等运算吗?还是足以限制许多操作的漂移?翻译量可以量化吗? ModelMatrix 可以量化吗?你能增加使用的浮点精度吗?平移量相对于位置量的大小是多少?

标签: java android opengl-es floating-point


【解决方案1】:
Matrix.setIdentity(ModelMatrix);
Matrix.translate(ModelMatrix, xmov,ymov,0);
Matrix.translate(ModelMatrix, -xmov,-ymov,0);

由于矩阵堆栈,总会产生浮点错误。

我最终删除它的方法是使用单独的矩阵进行此类关键转换:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-28
    • 1970-01-01
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多