3

我对 postScale 方法究竟如何计算矩阵的值有点困惑。这是代码:

Matrix m1 = new Matrix();
float[] values = { 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f };
m1.setValues(values);
Matrix m2 = new Matrix(m1);

m1.preScale(2f, 3f); //result: 2, 6, 3, 8, 15, 6, 14, 24, 9
m2.postScale(2f, 3f); //result: 1, 2, 3, 6, 7.5, 9, 3.5, 4, 4.5

文档说 preScale 的结果是 (Matrix * scale) 而 postScale 的结果是 (scale * Matrix)。但是如果我手动计算矩阵,结果会有所不同。

从右乘:

1 2 3 | 2 0 0   2   6 3
4 5 6 | 0 3 0 = 8  15 6
7 8 9 | 0 0 1   14 24 9

从左乘:

2 0 0 | 1 2 3    2  4  6
0 3 0 | 4 5 6 = 12 15 18
0 0 1 | 7 8 9    7  8  9

...左乘 (postScale) 返回的结果与我预期的不同

我什至研究了本机实现(Matrix_Delegate.java)。但我不知道问题出在哪里。有什么我想念的吗?

4

1 回答 1

2

在 setConcat(在 android/external/skia/src/core/SkMatrix.cpp 中)将至少一个是透视矩阵的两个矩阵相乘之后,它会调用一个名为“normalize_perspective”的方法。如果矩阵的最后一个单元格(右下角,如果是零索引,则为 mat[2][2],在此表示中为 mat[8])大于 1,它将矩阵中的每个数字除以 2。这当然描述了我们在这里看到的内容。

但是我们的友好矩阵是如何被认为是透视矩阵的呢?好。当我们执行 setValues() 时,类型被设置为未知。当 setConcat 调用 getType 时,它​​看到“未知”并决定对此做些什么。它调用computeTypeMask。computeTypeMask 查看第三列,发现它不是 [ 0 0 1 ],然后在矩阵类型上贴上 Perspective 标签。这发生在您的 m2 上。

但为什么这一切只是 postScale 的问题?preScale(除非 Skia 库是在定点模式下编译的)自己进行缩放,所以它永远不会进入 setConcat 来攻击这些岩石浅滩。

为什么 normalize_perspective 是个好主意?如果我知道,该死的。这可能与这些特定例程的预期 2d 图形应用程序有关。

对于这一切,你能做些什么?如果您的目标是 API 级别 11 或更高,那么 renderscript 的 Matrix3f 可能是您的朋友。如果不是,对不起,D-Fox,你的矩阵实现在另一个城堡里。

于 2012-07-02T14:50:09.337 回答