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就是浮云了。
有问题可以发信找我一起探讨。。
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就是浮云了。
有问题可以发信找我一起探讨。。
相关文章推荐
- 苹果开发 笔记(59)UIButton
- 另类总结BRD,MRD,PRD到底是干嘛用的,有啥区别。
- C语言中的未定义行为
- muduo::Connector、TcpClient分析
- 线程锁
- Webstorm 10.0.4 配置
- UVALive 5545 Glass Beads
- Python绘制excel表格到邮件正文区并发送脚本实例
- 百度推荐发布公告:上线广告变现工具
- mac中快速启动dock中程序
- HDU 4417 Super Mario // 线段树
- [数论]小于n且与n互素的个数(欧拉函数)
- Math.abs为Integer.Min_VALUE返回错误的值
- MapReduce 工作机制剖析
- 使用序列化实现对象的拷贝
- 判断一周的某一天的函数接口
- 【特种兵PPT教程】特种兵PPT知识分享——如何用PPT快速抠图?
- 粒子群算法 Particle Swarm Optimization, PSO(转贴收藏)
- Unicode与Ansi及UTF8与Ansi之间的转换
- JQuery AJAX 方法总结: