Android学习之Matrix

一、Matrix基础知识

Matrix是一个3x3的矩阵,主要用于缩放、平移、旋转等操作
在这里插入图片描述
其中:
MSCALE_X和MSCALE_Y控制缩放
MSKEW_X 和MSKEW_Y 控制错切
MTRANS_X和MTRANS_Y控制平移
MSCALE_X、MSCALE_Y和MSKEW_X、MSKEW_Y控制旋转
MPERSP用于处理透视(不常用)

由此可以看出Matrix的对图像的处理可分为四类基本变换:

Translate 平移变换
Rotate 旋转变换
Scale 缩放变换
Skew 错切变换

针对每种变换,Android提供了pre、set和post三种操作方式

Set 用于设置Matrix中的值。设置使用的不是矩阵乘法,而是直接覆盖掉原来的数值,所以,使用设置可能会导致之前的操作失效。

Pre 是先乘,因为矩阵的乘法不满足交换律,因此先乘、后乘必须要严格区分。先乘相当于矩阵运算中的右乘。

post是后乘,因为矩阵的乘法不满足交换律,因此先乘、后乘必须要严格区分。后乘相当于矩阵运算中的左乘。
1、平移变换

有一个点的坐标是 P(x_0, y_0),将其移动到,将其移动到 P(x,y) ,则在x轴和y轴方向移动的大小分别为:
△x = x − x_0
△y = y − y_0
就可以得到 x = △x + x_0 y = △y + y_0

用矩阵来表示的话,就可以写成:
在这里插入图片描述

2、旋转变换

有一个点的坐标是 P(x_0,y_0),相对坐标原点顺时针旋转θ后的情形,同时假定P点离
坐标原点的距离为r
在这里插入图片描述

那么:
x_0 = rcos⁡α
y_0 = rsin⁡α
x = rcos⁡(α+ θ)=rcos⁡α cos⁡θ - rsin⁡α sin⁡θ = x_0 cos⁡θ - y_0 sin⁡θ
y = rsin⁡(α+ θ)= rsin⁡α cos⁡θ + rsin⁡θ cos⁡α = y_0 cos⁡θ + x_0 sin⁡θ

用矩阵,就可以表示为:

在这里插入图片描述

3、缩放变换

图像在x轴和y轴方向分别放大k1和k2倍的话,那么图像中的所有点的x坐标和y坐标均会分别放大k1和k2倍,即:x = k1x_0 y = y= k2y_0

用矩阵来表示的话,就可以写成:

在这里插入图片描述

4、错切变换

错切变换的效果就是让所有点的x坐标(或者y坐标)保持不变,而对应的y坐标(或者x坐标)则按比例发生平移,且平移的大小和该点到x轴(或y轴)的垂直距离成正比。在Android中除了有上面说到的情况外,还可以同时进行水平、垂直错切。

用矩阵来表示的话,就可以写成:
在这里插入图片描述

5、对称变换

除了上面讲到的4中基本变换外,事实上,我们还可以利用Matrix,进行对称变换。所谓对称变换,就是经过变化后的图像和原图像是关于某个对称轴是对称的

<1> 对称轴是x轴,那么:

x= x_0
y= −y_0

用矩阵表示就是:
在这里插入图片描述
<2> 对称轴是y轴,那么:

x= -x_0
y= y_0

用矩阵表示就是:
在这里插入图片描述

<3> 对称轴是y = x

用矩阵表示就是:
在这里插入图片描述

<4> 对称轴是y = -x

用矩阵表示就是:
在这里插入图片描述

需要特别注意:在实际编程中,屏幕的y坐标的正向和数学中y坐标的正向刚好是相反的,所以在数学上y = x和屏幕上的y = -x才是真正的同一个东西,反之亦然。

二、Matrix特点

1、Matrix在View,图片,动画效果等各个方面均有运用

2、更加灵活,画布操作是对Matrix的封装,Matrix作为更接近底层的东西,必然要比画布操作更加灵活

3、封装很好,Matrix本身对各个方法就做了很好的封装,让开发者可以很方便的操作Matrix。

Matrix 是一个矩阵,最根本的作用就是坐标转换。所用到的变换均属于仿射变换,仿射变换是 线性变换(缩放,旋转,错切) 和 平移变换(平移) 的复合。除了透视可以改变z轴以外,其他的变换基本都是上述的原子变换(平移、缩放、翻转、旋转和错切),所以,只要最后一行是0,0,1则是仿射矩阵

三、Matrix方法解析

1、构造函数
public Matrix()  //直接创建一个单位矩阵
public Matrix(Matrix src) //根据提供的矩阵创建一个新的矩阵(采用deep copy)

在这里插入图片描述

2、isIdentity与isAffine
public boolean isIdentity()//判断是否是单位矩阵
public boolean isAffine()//判断是否是仿射矩阵
3、reset
public void reset() //重置矩阵
4、setTranslate
// 设置平移效果,参数分别是x,y上的平移量。
public void setTranslate(float dx, float dy)
5、setScale
public void setScale(float sx, float sy, float px, float py)
public void setScale(float sx, float sy)

sx,sy代表了缩放的倍数,px,py代表缩放的中心

6、setRotate
public void setRotate(float degrees, float px, float py)
public void setRotate(float degrees)
7、setSinCos
setSinCos(float sinValue,float cosValue,float px,float py)
setSinCos(float sinValue, float cosValue)

旋转:

sinValue:对应sin值 
cosValue:对应cos值 
px:中心的x坐标 
py:中心的y坐标
8、setSkew
setSkew(float kx, float ky, float px, float py)
setSkew(float kx, float ky)

kx,ky分别代表了x,y上的错切因子,px,py代表了错切的中心

9、setConcat
public boolean setConcat(Matrix a,Matrix b)
将当前matrix的值变为a和b的乘积
10、pre
preXXXX:以pre开头,例如preTranslate  前乘
postXXX:以post开头,例如postScale    后乘
例如:
Matrix matrix = new Matrix();
matrix.setTranslate(100, 1000);
matrix.preScale(0.5f, 0.5f);
11、setRectToRect
boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf)

将rect变换成rect
12、setPolyToPoly
boolean setPolyToPoly(float[] src, int srcIndex,float[] dst, int dstIndex,int pointCount)

通过指定的0-4个点,原始坐标以及变化后的坐标,来得到一个变换矩阵

如果指定0个点则没有效果
只指定一个点,可以达到平移效果
两个点,可以达到旋转效果或者缩放效果
使用3个点,可以产生错切效果
使用4个点,透视
13、invert
public boolean invert(Matrix inverse)

反转当前矩阵,如果能反转就返回true并将反转后的值写入inverse,否则返回false。当前矩阵*inverse=单位矩阵。

14、mapPoints
mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex,int pointCount)
mapPoints(float[] dst, float[] src)
mapPoints(float[] pts) 

映射点的值到指定的数组中,这个方法可以在矩阵变换以后,给出指定点的值。

dst:指定写入的数组 
dstIndex:写入的起始索引,x,y两个坐标算作一对,索引的单位是对,也就是经过两个值才加1 
src:指定要计算的点 
srcIndex:要计算的点的索引 
pointCount:需要计算的点的个数,每个点有两个值,x和y。
15、mapVectors
mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex,int vectorCount)
mapVectors(float[] dst, float[] src)
mapVectors(float[] vecs)

与上面的mapPoionts基本类似,这里是将一个矩阵作用于一个向量,由于向量的平移前后是相等的,所以这个方法不会对translate相关的方法产生反应,如果只是调用了translate相关的方法,那么得到的值和原本的一致。

16、mapRect
public boolean mapRect(RectF dst, RectF src)
public boolean mapRect(RectF rect)

返回值即是调用的rectStaysRect(),这个方法前面有讲过,这里把src中指定的矩形的左上角和右下角的两个点的坐标,写入dst中。

17、mapRadius
public float mapRadius(float radius)

返回一个圆圈半径的平均值,将matrix作用于一个指定radius半径的圆,随后返回的平均半径。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值