Android:Matrix->;前计算机辅助翻译和后计算机辅助翻译有什么不同?

Android:Matrix->;前计算机辅助翻译和后计算机辅助翻译有什么不同?,android,matrix,Android,Matrix,我正在使用缩放和旋转位图。现在我想知道Precocat和postconcat之间的区别是什么,或者更准确地说,它们之间的区别是什么: 据我目前所知,setRotate始终覆盖整个矩阵,而通过preRotate和postRotate,我可以对矩阵应用多个更改(例如缩放+旋转)。然而,无论是使用postRotate还是preRotate,我使用它们的案例都不会产生任何不同的结果。您的问题的答案并不真正针对Android;这是一道图形和数学题。这个答案有很多理论——你已经被警告过了!要想对你

我正在使用缩放和旋转位图。现在我想知道Precocat和postconcat之间的区别是什么,或者更准确地说,它们之间的区别是什么:


据我目前所知,setRotate始终覆盖整个矩阵,而通过preRotate和postRotate,我可以对矩阵应用多个更改(例如缩放+旋转)。然而,无论是使用postRotate还是preRotate,我使用它们的案例都不会产生任何不同的结果。

您的问题的答案并不真正针对Android;这是一道图形和数学题。这个答案有很多理论——你已经被警告过了!要想对你的问题有一个肤浅的回答,请跳到底部。而且,因为这是一篇冗长的长篇大论,我可能会有一两个打字错误,让事情变得不清楚。如果是这样的话,我提前道歉

在计算机图形学中,我们可以将像素(或三维顶点)表示为向量。如果你的屏幕是640x480,这里有一个2D向量指向屏幕中间的点(原谅我的劣质标记):

稍后我将解释为什么1很重要。转换通常使用表示,因为将它们链接在一起非常简单(而且非常有效),就像您提到的那样。要按1.5的因子缩放上述点,可以通过以下矩阵进行缩放:

[1.5   0   0]
[  0 1.5   0]
[  0   0   1]
您将获得以下新观点:

[480]
[360]
[  1]
它表示原始点,相对于屏幕的角(0,0)缩放1.5。这一点很重要:缩放始终是相对于原点进行的。如果要以其他点为中心(例如精灵的中间)进行缩放,则需要在原点之间的平移中“包裹”缩放。以下是将原点转换为原点的矩阵:

[1  0  -320]
[0  1  -240]
[0  0     1]
这将产生:

[320*1 + 1*-320]   [0]
[240*1 + 1*-240] = [0]
[     1*1      ]   [1]
你会认出上面的矩阵,位移坐标在右上角。这就是为什么1(“同质坐标”)是必要的:为这些坐标腾出空间,从而使使用乘法进行翻译成为可能。否则,它将不得不用矩阵加法来表示,这对人类来说更直观,但会使图形卡比现在更复杂

现在,矩阵乘法一般来说,所以当“添加”变换(通过将矩阵相乘)时,您需要指定是左乘法还是右乘法。它的区别在于转换的链接顺序。通过右键乘以矩阵(使用
preRotate()
),表明旋转步骤应该在您刚才要求的所有其他变换之前进行。这可能是你想要的,但通常不是

通常,这并不重要。例如,如果你只有一个变换,它就不重要了:)有时候,你的变换可以按任意顺序发生,具有相同的效果,比如缩放和旋转——我的线性代数已经过时了,但我相信在这种情况下,矩阵乘法实际上是可交换的,因为缩放矩阵是,它在对角线上反射自己。但真的,试想一下:如果我顺时针旋转一些图片10度,然后将其缩放到200%,看起来就像我先缩放它,然后旋转它一样


如果你在做一些奇怪的复合变换,你会开始注意到一个差异。我的建议是坚持使用
postRotate()

我昨天回答了这个问题,但今天我觉得有些不对劲,所以我在这里更正了答案:

matrix:  float[] values ={1.2f,0.5f,30,0.5f,1.2f,30,0,0,1};

//as we all know, the basic value in matrix,means no transformation added
matrix2:  float[] values2 ={1f,0,0,0,1f,0,0,0,1};

Let's say our matrix values are the values above.
1、 当我们进行如下转换时:

matrix.preTranslate(-50, -50);

is equals to do sequence transformation to matrix2 above like below:

matrix2.postTranslate(-50, -50);
matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);// note here
matrix2.postScale(1.2f, 1.2f);
matrix2.postTranslate(30, 30);
 matrix2.postSkew(0.4f,0.4f);
 matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);
 matrix2.postScale(1.2f, 1.2f);
 matrix2.postTranslate(30, 30);
2、 当我们进行如下转换时:

matrix.preRotate(50);

is equals to do sequence transformation to matrix2 like below:

matrix2.postRotate(50);
matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);
matrix2.postScale(1.2f, 1.2f);
matrix2.postTranslate(30, 30);
matrix.preScale(1.3f,1.3f);

is equals to do sequence transformation to matrix2 like below:

matrix2.postScale(1.3f,1.3f);
matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);
matrix2.postScale(1.2f, 1.2f);
matrix2.postTranslate(30, 30);
 matrix.preSkew(0.4f,0.4f);
3、 当我们进行如下转换时:

matrix.preRotate(50);

is equals to do sequence transformation to matrix2 like below:

matrix2.postRotate(50);
matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);
matrix2.postScale(1.2f, 1.2f);
matrix2.postTranslate(30, 30);
matrix.preScale(1.3f,1.3f);

is equals to do sequence transformation to matrix2 like below:

matrix2.postScale(1.3f,1.3f);
matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);
matrix2.postScale(1.2f, 1.2f);
matrix2.postTranslate(30, 30);
 matrix.preSkew(0.4f,0.4f);
4、 当我们进行如下转换时:

matrix.preRotate(50);

is equals to do sequence transformation to matrix2 like below:

matrix2.postRotate(50);
matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);
matrix2.postScale(1.2f, 1.2f);
matrix2.postTranslate(30, 30);
matrix.preScale(1.3f,1.3f);

is equals to do sequence transformation to matrix2 like below:

matrix2.postScale(1.3f,1.3f);
matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);
matrix2.postScale(1.2f, 1.2f);
matrix2.postTranslate(30, 30);
 matrix.preSkew(0.4f,0.4f);
等于对matrix2进行序列变换,如下所示:

matrix.preTranslate(-50, -50);

is equals to do sequence transformation to matrix2 above like below:

matrix2.postTranslate(-50, -50);
matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);// note here
matrix2.postScale(1.2f, 1.2f);
matrix2.postTranslate(30, 30);
 matrix2.postSkew(0.4f,0.4f);
 matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);
 matrix2.postScale(1.2f, 1.2f);
 matrix2.postTranslate(30, 30);

根据这些文档,M.precocat(other)>M'=M*other,M.postConcat(other)>M'=other*M,我目前正在尝试其中的一些方法,但似乎“pre”会在您已经完成的操作之后设置新操作,“post”以前会这样做。我在缩放然后平移,它需要缩放然后平移,因为平移是在缩放坐标中。如果我是“pre”则有效,但如果我是“post”则无效。这个符号让我感到困惑,所以如果我错了,请告诉我。我还必须将文档加倍和加倍。命名方案相当混乱,所以我可能会把它颠倒过来。不过,我不确定我是否理解您的表示法:)
other*m
是一个左乘法,应该产生
m
的转换,然后是
other
。我想。我从这里得到了这个符号:我也发现命名令人困惑。爱简洁而深入的解释+1.@Cheezmeister你能推荐一些我能找到更多关于计算机图形学的资料来源吗,像你的答案一样详细解释一下