Matrix详解

【转】http://www.eoeandroid.com/thread-177983-1-1.html

最近努力学习了一下Matrix,结合android提供的Matrix类恶补了一下线性代数的知识(矩阵革命)。。下面对Matrix做一下详细解析。

android提供了Matrix类用于对图像进行移动缩放旋转等等操作。看似有点麻烦复杂,还有pre、pro等的区别,其实掌握了线性代数的Matrix基础知识后,就会发现真是so easy。那下面跟随本帖来场矩阵革命吧。。

从最基本的开始,将点P(x,y) x轴移动a个单位,y轴移动b个单位到(x',y')处,会移动吧,无非就是x'=x+a;y'=y+b;用矩阵表示如下(中括号省略,因为没法输入。。):
x'      1   0   a      x
y'  =  0  1   b   * y
1       0   0  1      1
很显然通过矩阵乘法可以得到如下结论:x'=x+a;y'=y+b;(忘了矩阵乘法的童鞋自觉找谷哥。。)。中间含有a、b的那个矩阵就是参数矩阵,也就对应着android提供的Matrix类。

有个这个最基本的矩阵等式后,就可以推出N多等式来,比如放大操作(x'=x*a;y'=y*a),旋转操作(x’ = x cosθ+ y sinθ;y'=-xsinθ+ycosθ)等,只要摆好刚才那个矩阵乘法等式然后填充参数矩阵的相关参数即可。

比如android中将原图像水平翻转,可以这样写:
float[] floats=new float[] { -1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f };
Matrix matrix = new Matrix();
matrix.setValues(floats);
return Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
其中floats数组就对应了刚才介绍那个参数矩阵。

当然android封装了很多方法来简化我们的代码,比如matrix.setTranslate(a,b);就相当于将(x,y)x轴移动a,y轴移动b。完全等价于matrix.setValues(new float[1,0,a,0,1,b,0,0,1]);

OK,单次更新图像就到这了。很简单吧。。下面就是稍微复杂点的复合更新。
将点P(x,y)绕着点(a,b)旋转θ角度。为了达到这个目的,一般分为三步来执行。先将坐标系原点移动到(a,b)点,然后图像绕原点旋转θ角度,然后再将坐标原点移回原来的位置。其中,移动坐标原点到(a,b)点,相当于将图像x轴移动-a,y轴移动-b。将上述三步表示成矩阵为:
1   0   -a          cosθ  -sinθ  0              1    0   a
0  -1  -b           sinθ   cosθ  0             0    -1   b
0  0   1            0         0      1             0    0    1
下面引入一个定理,很重要:设对给定的图像依次进行了基本变化F1、F2、F3…..、Fn,它们的变化矩阵分别为T1、T2、T3…..、Tn,图像复合
变化的矩阵T 可以表示为:T = TnTn-1…T1。
意思就是矩阵乘法是要按照步骤的顺序倒序来乘的。那么上面的三步表示为矩阵乘法就是:
1   0   a            cosθ  -sinθ  0                1    0   -a
0  -1  b     *      sinθ   cosθ  0       *       0    -1  -b
0  0   1             0         0      1               0    0    1
OK,有兴趣的童鞋可以用几何知识验证一下。

有了上面的知识,就可以来理解android Matrix里的pre和post的用法和区别了。由于矩阵乘法不满足交换律,即AB!=BA.pre和post就是针对这个问题而产生的。
pre就是先做,当然在矩阵乘法中对应着右乘法。post是后做,当然在矩阵乘法中对应着左乘。于是上面提到的问题用android提供的方法可以写为:
matrix.setTranslate(a,b);
matrix.preRotate(θ);
matrix.preTranslate(-a,-b);
即先将图像x轴移动-a,y轴移动-b(具体操作是将原点移动到(a,b));然后绕原点旋转θ角;然后将坐标系移动到原点(原点移动(-a,-b),图像移动(a,b))。
有一个问题要特别注意,就是调用setXXXXXXX时,会内部调用reset()将矩阵重置。所以setXXXXX一般是放到最前面写(只是写到前面,不代表步骤是在前面),并且在一个复合变化中只调用一次。

OK。到这里android提供的Matrix就应该没啥问题了。帖子中大量用到了线性代数的矩阵知识,回去补习好了这些基本知识android Matrix就是浮云了。

有问题可以发信找我一起探讨。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值