android 单位矩阵,Android中关于矩阵(Matrix)前乘后乘的一些认识

在上一篇文章中,我们讲到,在Android中,scale(缩放),rotation(旋转)和 translation(平移)都是以矩阵(Matrix)的形式定义的,实际上在图形学中,这些平面图形的变换都是以矩阵的形式存在的。先来回顾一下,下面,左中右分别scale(缩放),rotation(旋转)和 translation(平移)在Android中的矩阵表示:

531ca0de926060202458c855c775f9fa.png

如果只是单纯的应用某一个变换,我们都知道直接用矩阵去乘上对应的点就可以了。但是对于缩放和旋转来说,它们的轴点是基于原点(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);

}

则其效果如右图所示:

27866f52bb99476027ae54f5b0712a7f.png

那么我们如果想让它基于图片中心缩放,应该该怎么办?我们上一篇文章也说过了,要用到组合变换,

1)先将图片由中心平移到原点,这是应用变换 T

2)对图应用缩放变换 S

3)再将图片平移回到中心,应用变换 -T

下面给出它们的组合变换的公式:

f9625616cdb6f489230e75c876596285.png

在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 是图片的中心):

a4bdfbaef6f14f3ea1821bf06c523dd0.png

我们看到代码中,我们在进行了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)前乘和后乘所对应的图形学中矩阵中右乘和左乘的操作了。

不知道理解有没有错误,如有错误 ,希望有朋友能够指正,谢谢大家,另祝大家新年快乐!

————————————————

版权声明:本文为CSDN博主「linmiansheng」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

#转载请注明出处 www.skcircle.com 《少有人走的路》勇哥的工业自动化技术网站。如果需要本贴图片源码等资源,请向勇哥索取。

收藏 | 0点赞 | 0打赏作者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值