簡體   English   中英

防范Java中的浮點錯誤

[英]safeguard against floating point errors in java

隨着游戲中渲染的幀數增加到超過特定限制,而不是為以下類型的矩陣轉換獲取單位矩陣:

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

盡管這不是必需的 ,但是完整的代碼在這里: 繞z軸旋轉

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM