Android中关于矩阵(Matrix)前乘后乘的一些认识
在上一篇文章中,我们讲到,在Android中,scale(缩放),rotation(旋转)和 translation(平移)都是以矩阵(Matrix)的形式定义的,实际上在图形学中,这些平面图形的变换都是以矩阵的形式存在的。先来回顾一下,下面,左中右分别scale(缩放),rotation(旋转)和 translation(平移)在Android中的矩阵表示:
如果只是单纯的应用某一个变换,我们都知道直接用矩阵去乘上对应的点就可以了。但是对于缩放和旋转来说,它们的轴点是基于原点(0,0)的,如下图,我们将它缩小1倍,代码如下:
public void onDraw(Canvas canvas){
canvas.drawBitmap(bitmap, 0, 0, null);
matrix.reset();
matrix.postScale(0.5f, 0.5f);
canvas.drawBitmap(bitmap, matrix, null);
}
则其效果如右图所示:
那么我们如果想让它基于图片中心缩放,应该该怎么办?我们上一篇文章也说过了,要用到组合变换,
1)先将图片由中心平移到原点,这是应用变换 T
2)对图应用缩放变换 S
3)再将图片平移回到中心,应用变换 -T
下面给出它们的组合变换的公式:
在Android中的代码如下:
public void onDraw(Canvas canvas){
canvas.drawBitmap(bitmap, 0, 0, null);
matrix.reset();
matrix.postScale(0.5f, 0.5f);
matrix.preTranslate(-pivotX, -pivotY);
matrix.postTranslate(pivotX, pivotY);
canvas.drawBitmap(bitmap, matrix, null);
}
我们看一下加上平移之后的效果图(其中pivotX 和 pivotY 是图片的中心):
我们看到代码中,我们在进行了scale之后呢,还给图片设置了下面两个平移的变换:
matrix.preTranslate(-pivotX, -pivotY);
matrix.postTranslate(pivotX, pivotY);
什么是PreTranlsate呢,什么又是postTranslate呢?我们先来看一下Android中的定义吧。
preTranslate:
/**
* Preconcats the matrix with the specified translation.
* M' = M * T(dx, dy)
*/
public boolean preTranslate(float dx, float dy) {
return native_preTranslate(native_instance, dx, dy);
}
postTranslate:
/**
* Postconcats the matrix with the specified translation.
* M' = T(dx, dy) * M
*/
public boolean postTranslate(float dx, float dy) {
return native_postTranslate(native_instance, dx, dy);
}
我们可以看到,pre是拿当前的矩阵乘以T,而post是拿T来乘以当前的矩阵,(矩阵的乘法是不满足交换率的,所以这两种乘法的结果是不一样的)
在图形学中,矩阵M右乘A,表示的是 A * M,而矩阵 M 左乘 A,则表示的是 M * A,可以形象地理解为右乘就是从右边乘进来,左乘就是从左边乘进来。
一比较,我们可以看出,pre其实执行的就是右乘的操作,而post执行的就是左乘的操作。
这是因为,在图像处理中,越靠近右边的矩阵越先执行,所以pre(也就是先的意思)所设置的矩阵T(Scale,Rotation也是一样的)就会先于其一开始设置的Scale执行,而post(后的意思)的因为是左乘,所以它会放在最左边,那么就会最后执行。
所以,上面三步的意思其实就是:
1)在当前的矩阵左边加一个Scale的操作,因为之前没有其的操作(reset了),那么当前的矩阵其实就只是 S 了。
2)在当前的矩阵(S)执行前,先执行一个平移到原点的操作(preTranslate),其实也就是进行右乘(S * T)。
3)在当前的矩阵(S * T)执行后,再执行一个从原点平移到中心点的操作(postTranslate),也就是进行一个左乘(-T * S * T)。
这就是Android中矩阵(Matrix)前乘和后乘所对应的图形学中矩阵中右乘和左乘的操作了。
不知道理解有没有错误,如有错误 ,希望有朋友能够指正,谢谢大家,另祝大家新年快乐!
下面是上一篇文章,关于图形学中矩阵和图形变换的关系,有兴趣的朋友也可以读一下:
上一篇: 矩阵链乘