博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android矩阵变换讲解Matrix
阅读量:4180 次
发布时间:2019-05-26

本文共 3329 字,大约阅读时间需要 11 分钟。

        在二维的平面上,对图片进行处理时,主要可以分为平移,缩放和旋转,如果是直接对图片坐标进行处理显然是很复杂的,这是我们就可以用到矩阵,在矩阵中有单位矩阵这么个概念,我的理解就是这是一个标准的坐标系,其他的变换都是基于这个坐标来的,可能理解有出入,不过这我能想到跟实际相关联的。

        下面先来看看2D图形变换中的

        平移:

        我们先假设平面上有一点(x,y),这个点向x,y方向上平移了dx,dy,变换后的坐标(X,Y)=(x+dx,y+dy),用矩阵表示:

1 0 dx   x     X                               1 0 dx[ 0 1 dy ][y] = [Y] 我们可以发现平移变换矩阵是: [0 1 dy]  0 0 1    1     1                               0 0 1

        缩放:

        同样的假设平面上一点坐标(x,y),在x,y方向上缩放了sx,sy,变换后的坐标(X,Y)=(sx*x,sy*y),用矩阵表示:

sx 0  0   x     X                               sx 0  0[ 0  sy 0 ][y] = [Y] 我们可以发现缩放变换矩阵是: [0  sy 0]  0  0  1   1     1                               0  0  1

        旋转:

        旋转稍微复杂一点,不过先同样假设一点坐标(x,y)到原点的坐标是R,到x轴的坐标是β,以原点为圆心,旋转θ度,那么变换后的坐标是:x=R*cosβ,y=R*sinβ,X=Rcos(β+θ),Y=sin(β+θ),对X,Y进行合角公式变换:

X=R*cosβ*cosθ-R*sinβ*sinθ=x*cosθ-y*sinθ

Y=R*sinβ*cosθ+R*cosβ*sinθ=y*cosθ+x*sinθ,用矩阵表示:

cosθ -sinθ 0   x     X                               cosθ -sinθ  0[ sinθ  cosθ 0 ][y] = [Y] 我们可以发现旋转变换矩阵是: [sinθ  cosθ  0]  0      0     1   1     1                                 0     0     1

根据我自己的理解,矩阵就是坐标系,单位矩阵就是标准坐标系,对于二维平面,可以用3x3的单位矩阵表示。对于矩阵的理解(限于二维平面):第一行我理解是x的变换,第二行理解为y的变换,第三行就是常数了,正好与上面的对应上。对于矩阵的变换其实就是对坐标系的变换,不知道是不是可以这样去理解。

        接下来看看Android中Matrix是如何变换的:先看Android是如何描述这个类的:

* The Matrix class holds a 3x3 matrix for transforming coordinates.

        解释:矩阵类用一个3x3的矩阵对坐标进行转换。(方法基本都是native的,就没必要看源码了)

        来看看Matrix是如何作用的:

private void initMatrix(){        float[] arr = {
1,0,0, 0,1,0, 0,0,1}; StringBuilder builder = new StringBuilder(); Matrix matrix = new Matrix(); matrix.setValues(arr); matrix.setTranslate(2,2);// matrix.setScale(2,2);// matrix.setRotate((float) Math.toDegrees(Math.PI/3)); matrix.getValues(arr); builder.append("{"); for (float v : arr) { builder.append(v+","); } builder.append("}"); Log.d(TAG, "initMatrix: arr = "+builder); }

 输出结果(三次分别输出,与上面设置的方法对应):

initMatrix: arr = {
1.0,0.0,2.0, 0.0,1.0,2.0, 0.0,0.0,1.0,}initMatrix: arr = {
2.0,0.0,0.0, 0.0,2.0,0.0, 0.0,0.0,1.0,}initMatrix: arr = {
0.49999997,-0.86602545,0.0, 0.86602545,0.49999997, 0.0, 0.0, 0.0, 1.0,}

转换后是不是就和上面是一样了,可以好好体会下。这个还是比较抽象的,不过理解了就比较简单了。

        上面我们得到了一个转换矩阵,现在我们就用这个矩阵来转换一个矩形,看看矩形有什么变化:

private void initMatrix(){        float[] arr = {
1,0,0, 0,1,0, 0,0,1}; StringBuilder builder = new StringBuilder(); Matrix matrix = new Matrix(); matrix.setValues(arr);// matrix.setTranslate(2,2); matrix.setScale(2,2);// matrix.setRotate((float) Math.toDegrees(Math.PI/3)); RectF rect = new RectF(); rect.set(0,0,6,6); matrix.mapRect(rect); Log.d(TAG, "initMatrix: rect = "+rect.left+" "+rect.top+" "+rect.right+" "+rect.bottom); matrix.getValues(arr); builder.append("{"); for (float v : arr) { builder.append(v+","); } builder.append("}"); Log.d(TAG, "initMatrix: arr = "+builder.toString()); }

输出结果(三次分别输出,与上面设置的方法对应),主要是看矩形输出结果:

initMatrix: rect = 2.0   2.0   8.0   8.0initMatrix: rect = 0.0   0.0   12.0   12.0initMatrix: rect = -5.1961527   0.0   2.9999998   8.196153
如果这个矩形是一个图片,那这样变换就是图片的变换了。

转载地址:http://mzhai.baihongyu.com/

你可能感兴趣的文章
Linux内核-------同步机制(二)
查看>>
面试题31-------连续子数组的最大和(数组)
查看>>
epoll 实现Chat
查看>>
21. Merge Two Sorted Lists(链表)
查看>>
2. Add Two Numbers(链表)
查看>>
637. Average of Levels in Binary Tree(Tree)
查看>>
226. Invert Binary Tree(Tree)
查看>>
328. Odd Even Linked List(链表)
查看>>
199. Binary Tree Right Side View(Tree)
查看>>
230. Kth Smallest Element in a BST(Tree)
查看>>
求字符串的最长回文串-----Manacher's Algorithm 马拉车算法
查看>>
回溯法常用的解题模板和常见题型
查看>>
深入分析Java I/O 的工作机制
查看>>
动态规划的套路----左神
查看>>
KMP算法简解
查看>>
左神算法课进阶版总结
查看>>
左神算法基础班总结
查看>>
Linux性能优化
查看>>
进程间的通信---UNIX高级环境编程
查看>>
基于SSH开发的城市公交管理系统 JAVA MySQL
查看>>