您的位置:首页 > 其它

Matrix详解

2015-08-10 22:42 183 查看
最近努力学习了一下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就是浮云了。

有问题可以发信找我一起探讨。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: