您的位置:首页 > 移动开发 > Android开发

android 图形变换矩阵讲解

2016-08-14 10:18 363 查看


看上图,这里表示了屏幕的坐标系,其中的x,y轴是大家所熟知的,但是其实,一个物体他是存在于一个三维空间的,所以必然会有z轴。我们的屏幕,就像是一个窗口,透过它,我们看到了屏幕后面的世界,那里面有各种物体,我们看到的是映射在x,y平面上的一个投射图像。屏幕就像是一个镜头一样,将里面的物体映射到x,y平面上,成为一个二维的图像。那么如果,我们把屏幕这个镜头沿着z轴,拉远或者拉进,那么图像会有什么变化呢,肯定会变小或者变大。就好比坐在飞机上透过窗口看地面的汽车,和在地面上看到的大小是不同的。

结论就是,在屏幕上显示的像素,不仅仅有x,y坐标,其实还有z轴的影响。所以这里对应的像素描述由一个3行一列的矩阵来表示:



x,y分别代表x,y轴上的坐标,而1代表屏幕在z轴上的坐标为默认的。如果将1变大,那么屏幕会拉远, 图形会变小

图像的平移原理:

假设一个点a坐标为(x0,y0)经过水平平移了b距离后变成了点c坐标为(x1,y1)。

因为是水平平移,所以a和b的y坐标的大小是相同的。但是a和b x的坐标点是不同的。

所以有如下公式:

X1 = x0 + b;
Y1 = y0;

怎么把它转换成矩阵呢?

高等数学中有个叫系数矩阵的东西。如下:

系数矩阵:

方程组可以写成矩阵的形式,由未知数的系数构成的矩阵就叫系数矩阵.比如上面的的方
程组的系数矩阵就是:

x1  1 0 b  x0

y1 = 0 1 0 * y0

1   0 0 1  1

教科书告诉你,计算规则是,第一个矩阵第一行的每个数字(2和1),各自乘以第二个矩阵第一列对应位置的数字(1和1),然后将乘积相加( 2 x 1 + 1 x 1),得到结果矩阵左上角的那个值3。



根据这个结果可知系数矩阵:

x1 = 1 * x0 + 0 * y0 + b * 1 = x0 + b;

y1 = 0 * x0 + 1 * y0 + 0 * 1 = y0;

图像旋转原理:

这里我们通过一个旋转变换来看看原理,其实一张图片围绕一个点旋转,也就是所有的点都围绕一个点旋转,所以只需要关注一个点的情况即可:

假定有一个点 ,相对坐标原点顺时针旋转后的情形,同时假定P点离坐标原点的距离为r,如下图:



那么就有:



换做矩阵运算就如下图:



最后把这个矩阵通过matrix.setValues的方法设置一下,然后通过canvas.drawBitmap(bmp, matrix, paint);就可以把
该旋转矩阵应用到bitmap上面了。
三角函数转换公式如下:

sin(A+B)=sinAcosB+cosAsinB
sin(A-B)=sinAcosB-cosAsinB
cos(A+B)=cosAcosB-sinAsinB
cos(A-B)=cosAcosB+sinAsinB


另外图像的复合变化:

设对给定的图像依次进行了基本变化F1、F2、F3…..、Fn,它们的变化矩阵分别为T1、T2、T3…..、Tn,图像复合变化的矩阵T可以表示为:T = TnTn-1…T1。

如果想要对图像进行先平移再旋转,只需要把他们两个矩阵相乘即可。

为什么相乘就可以达到先平移再旋转了?

论证一下:

x1    1 0 b        x0

y1 = 0 1 0   *    y0

1       0 0 1        1

是点(x0,y0)在x方向上平移b后的结果为点(x1,y1)。
如果再进行旋转的角度为A,旋转后的点为(x2,y2),那么就有如下公式。

x2  x1       cosA    -sinA  0   

y2 = y1  *    sinA    cosA   0  

1   1        0      0    1

又已知

x1   1 0 b    x0
y1 = 0 1 0 * y0
1   0 0 1    1
所以可以得出

x2    1 0 b      cosA  -sinA  0     x0
y2 = 0 1 0 *  sinA   cosA   0  *  y0
1      0 0 1       0         0       1     1 

有关于变换的set方法都可以带来不同的效果,但是每个set都会把上个效果清除掉,例如依次调用了setSkew,setTranslate,那么最终只有setTranslate会起作用,那么如何才和将两种效果复合呢。Matrix给我们提供了很多方法。但是主要都是2类:

preXXXX:以pre开头,例如preTranslate 

postXXXX:以post开头,例如postScale

这里matrix前乘了一个scale矩阵,换算成数学式如下:



从上面可以看出,最终得出的matrix既包含了缩放信息也有平移信息。 

后乘自然就是matrix在后面,而缩放矩阵在前面,由于矩阵前后乘并不等价,也就导致了他们的效果不同。我们来看看后乘的结果:



可以看到,结果跟上面不同,并且这也不是我们想要的结果,这里缩放没有更改,但是平移被减半了,换句话说,平移的距离也被缩放了。所以需要注意前后乘法的关系。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: