0

我有这个 3x3 矩阵,我用它来执行基本的转换,如平移、缩放和旋转,但旋转部分不能正常工作。对于任何大于 30 度左右的角度,它看起来……很奇怪。

该方法如下所示:

public void rotate(float angle) {
    double rads = angle * (Math.PI/180);
    float sin = (float) Math.sin(rads);
    float cos = (float) Math.cos(rads);

    matrix[0][0] = cos;
    matrix[0][1] = -sin;
    matrix[1][0] = sin;
    matrix[1][1] = cos; 
}

以及应用转换的方法:

对于 X:

public float[] applyTransformX(float[] x, float[] y) {
    float[] transformed = new float[x.length];
    for(int i=0; i<x.length; i++) {
        transformed[i] = (x[i] * matrix[0][0]) + (y[i] * matrix[0][1] + matrix[0][2]);
        System.out.println((x[i] * matrix[0][0]) + (y[i] * matrix[0][1] + matrix[0][2]));

    }
    return transformed;
}

对于 Y:

public float[] applyTransformY(float[] x, float[] y) {
    float[] transformed = new float[x.length];
    for(int i=0; i<x.length; i++) {
        transformed[i] = (x[i] * matrix[1][0]) + (y[i] * matrix[1][1] + matrix[1][2]);
    }
    return transformed;
}

我在这里缺少任何基本的东西吗?我知道我没有围绕一个固定点进行转换。这可能是我遇到这个问题的原因吗?

正如我所说,平移和缩放正在正常工作。

4

2 回答 2

1

我能想到的只是,您添加的三个术语的大小差异可能会导致舍入误差 get eachx[i]和 to get each y[i]。我的直觉是最后添加翻译术语,以便相当大的翻译不会导致旋转导致的术语失去意义。这只需要您删除一些括号,以便标准的从左到右的操作顺序开始。换句话说,在计算 X 值的方法中,写:

transformed[i] = x[i] * matrix[0][0] + y[i] * matrix[0][1] + matrix[0][2];

没有任何括号。同样,在计算 Y 值时,写

transformed[i] = x[i] * matrix[1][0] + y[i] * matrix[1][1] + matrix[1][2];

如果这没有帮助,那么请发布一些实际数字,以便我们可以看到哪些计算可能会导致重要性丧失。这对小角度有效的事实表明您看到的是舍入误差,而不是实际不正确的计算方法。

于 2012-09-25T22:34:57.447 回答
0

问题在于 transformed[i]两种情况的计算:对于 X 它应该是:

transformed[i] = (x[i] * matrix[0][0]) + (y[i] * matrix[0][1]);

对于 Y 它应该是:

transformed[i] = (x[i] * matrix[1][0]) + (y[i] * matrix[1][1]);

如果您包含matrix[0][2]并且matrix[1][2]这将用于 Z 组件,但是对于围绕 Z 轴的旋转,这些应该评估为 0(matrix[2][2]尽管是完整的,但应该是 1)。你可能只是忘了重新初始化它们……</p>

于 2012-09-25T22:19:24.887 回答