android将矩阵转换成字节数组,Android Matrix矩阵

Matrix

Matrix是一个矩阵,主要功能是坐标映射,数值转换,在View,图片,动画效果等各个方面均有运用。

基本变换有4种:

平移(Translate)

缩放(Scale)

旋转(Rotate)

错切(Skew)

矩阵运算

矩阵加减法:

就是相同位置的数字相加

c83f59613c18

矩阵相加.png

矩阵减法也类似

矩阵乘以一个常数

就是所有位置都乘以这个数:

c83f59613c18

矩阵乘常数.png

矩阵乘以矩阵

c83f59613c18

矩阵乘以矩阵.png

计算规则是,第一个矩阵第一行的每个数字(2和1),各自乘以第二个矩阵第一列对应位置的数字(1和1),然后将乘积相加( 2 x 1 + 1 x 1),得到结果矩阵左上角的那个值3。也就是说,结果矩阵第m行与第n列交叉位置的那个值,等于第一个矩阵第m行与第二个矩阵第n列,对应位置的每个值的乘积之和

矩阵的本质就是线性方程式,两者是一一对应关系

c83f59613c18

线性方程式.png

矩阵的最初目的,只是为线性方程组提供一个简写形式。

c83f59613c18

矩阵.png

四种变换

1、缩放(Scale)

c83f59613c18

缩放.png

2.错切(Skew)

c83f59613c18

错切.png

3.旋转(Rotate)

假定一个点 A(x0, y0) ,距离原点距离为 r, 与水平轴夹角为 α 度, 绕原点旋转 θ 度, 旋转后为点 B(x, y) 如下:

c83f59613c18

旋转.png

4.平移(Translate)

c83f59613c18

平移.png

Matrix复合原理

常用的四大变换操作,每一种操作在Matrix均有三类,前乘(pre),后乘(post)和设置(set)

前乘(pre):前乘相当于矩阵的右乘

后乘(post):前乘相当于矩阵的左乘

设置(set):设置使用的不是矩阵乘法,而是直接覆盖掉原来的数值

例如:

Matrix m = new Matrix();

m.reset();

m.preTranslate(tx, ty);

m.preScale(sx, sy);

c83f59613c18

左乘.png

Matrix m = new Matrix();

m.reset();

m.postScale(sx, sy);

m.postTranslate(tx, ty);

c83f59613c18

右乘.png

pre 和 post 就是右乘或者左乘的区别,pre 和 post 不能影响程序执行顺序,而程序每执行一条语句都会得出一个确定的结果,从实际上来说,由于矩阵乘法满足结合律,所以不论你说是靠右先执行还是靠左先执行,从结果上来说都没有错

Matrix方法

1.Matrix ()

2.Matrix (Matrix src)

3.void set (Matrix src)

4.void reset ()

重置当前Matrix(将当前Matrix重置为单位矩阵)。

5.void setValues (float[] values)

setValues的参数是浮点型的一维数组,长度需要大于9,拷贝数组中的前9位数值赋值给当前Matrix。

6.void getValues (float[] values)

getValues和setValues是一对方法,参数也是浮点型的一维数组,长度需要大于9,将Matrix中的数值拷贝进参数的前9位中。

7.boolean invert (Matrix inverse)

求矩阵的逆矩阵,简而言之就是计算与之前相反的矩阵,如果之前是平移200px,则求的矩阵为反向平移200px,如果之前是缩小到0.5f,则结果是放大到2倍

8.isAffine

判断矩阵是否是仿射矩阵, 基本上这个一直是true,因为我们所使用的变换基本上都是放射变换。

9.isIdentity

判断是否为单位矩阵,什么是单位矩阵呢,新创建的Matrix和重置后的Matrix都是单位矩阵,不过,只要随意操作一步,就不在是单位矩阵了。

10.setConcat

Matrix类还提供了直接矩阵计算方式。Matrix a=new Matrix()相当于创建一个单位矩阵。

a.set(b),就是赋值a = b;

a.preConCat(b),相当于前乘,即 a=a×b;

a.postConCat(b),相当于前乘,即 a=b×a;

c.setConcat(a,b),相当于c=a×b;

11.void setTranslate(float dx, float dy)

设置平移效果,参数分别是x,y上的平移量。

12.void setScale(float sx, float sy, float px, float py)

void setScale(float sx, float sy)

两个方法都是设置缩放到matrix中,sx,sy代表了缩放的倍数,px,py代表缩放的中心。

13.void setRotate(float degrees, float px, float py)

void setRotate(float degrees)

和上面类似

14.void setSkew(float kx, float ky, float px, float py)

void setSkew(float kx, float ky)

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

15.mapPoints

计算一组点基于当前Matrix变换后的位置,(由于是计算点,所以参数中的float数组长度一般都是偶数的,若为奇数,则最后一个数值不参与计算)

(1) void mapPoints (float[] pts)

void mapPoints (float[] pts) 方法仅有一个参数,pts数组作为参数传递原始数值,计算结果仍存放在pts中

// 初始数据为三个点 (0, 0) (80, 100) (400, 300)

float[] pts = new float[]{0, 0, 80, 100, 400, 300};

// 构造一个matrix,x坐标缩放0.5

Matrix matrix = new Matrix();

matrix.setScale(0.5f, 1f);

// 输出pts计算之前数据

Log.i(TAG, "before: "+ Arrays.toString(pts));

// 调用map方法计算

matrix.mapPoints(pts);

// 输出pts计算之后数据

Log.i(TAG, "after : "+ Arrays.toString(pts));

before: [0.0, 0.0, 80.0, 100.0, 400.0, 300.0]

after : [0.0, 0.0, 40.0, 100.0, 200.0, 300.0]

(2)void mapPoints (float[] dst, float[] src)

(3)void mapPoints (float[] dst, int dstIndex,float[] src, int srcIndex, int pointCount)

16.float mapRadius (float radius)

测量半径,由于圆可能会因为画布变换变成椭圆,所以此处测量的是平均半径。

float radius = 100;

float result = 0;

// 构造一个matrix,x坐标缩放0.5

Matrix matrix = new Matrix();

matrix.setScale(0.5f, 1f);

Log.i(TAG, "mapRadius: "+radius);

result = matrix.mapRadius(radius);

Log.i(TAG, "mapRadius: "+result);

17.boolean mapRect (RectF rect)

boolean mapRect (RectF dst, RectF src)

测量矩形变换后位置。

RectF rect = new RectF(400, 400, 1000, 800);

// 构造一个matrix

Matrix matrix = new Matrix();

matrix.setScale(0.5f, 1f);

matrix.postSkew(1,0);

Log.i(TAG, "mapRadius: "+rect.toString());

boolean result = matrix.mapRect(rect);

Log.i(TAG, "mapRadius: "+rect.toString());

Log.e(TAG, "isRect: "+ result);

18.mapVectors

测量向量。

mapVectors 与 mapPoints基本上是相同的,可以直接参照上面的mapPoints使用方法。

而两者唯一的区别就是 mapVectors 不会受到位移的影响,由于向量的平移前后是相等的,这符合向量的定律

float[] src = new float[]{1000, 800};

float[] dst = new float[2];

// 构造一个matrix

Matrix matrix = new Matrix();

matrix.setScale(0.5f, 1f);

matrix.postTranslate(100,100);

// 计算向量, 不受位移影响

matrix.mapVectors(dst, src);

Log.i(TAG, "mapVectors: "+Arrays.toString(dst));

// 计算点

matrix.mapPoints(dst, src);

Log.i(TAG, "mapPoints: "+Arrays.toString(dst));

//打印:

mapVectors: [500.0, 800.0]

mapPoints: [600.0, 900.0]

19.setPolyToPoly

boolean setPolyToPoly (

float[] src, // 原始数组 src [x,y],存储内容为一组点

int srcIndex, // 原始数组开始位置

float[] dst, // 目标数组 dst [x,y],存储内容为一组点

int dstIndex, // 目标数组开始位置

int pointCount) // 测控点的数量 取值范围是: 0到4

pointCount的意义

0 相当于reset

1 相当于translate

2 可以进行 缩放、旋转、平移 变换

3 可以进行 缩放、旋转、平移、错切 变换

4 可以进行 缩放、旋转、平移、错切以及任何形变

20.setRectToRect

boolean setRectToRect (RectF src, // 源区域

RectF dst, // 目标区域

Matrix.ScaleToFit stf) // 缩放适配模式

将源矩形的内容填充到目标矩形中,然而在大多数的情况下,源矩形和目标矩形的长宽比是不一致的,到底该如何填充呢,这个填充的模式就由第三个参数 stf 来确定

ScaleToFit 是一个枚举类型,共包含了四种模式

CENTER 居中,对src等比例缩放,并最大限度的填充变换后的矩形,将其居中放置在dst中。

START 顶部,对src等比例缩放,并最大限度的填充变换后的矩形,将其放置在dst的左上角。左上对齐

END 底部,对src等比例缩放,并最大限度的填充变换后的矩形,将其放置在dst的右下角。 右下对齐

FILL 充满,拉伸src的宽和高,使其完全填充满dst。

21.rectStaysRect

判断矩形经过变换后是否仍为矩形

Matrix实用技巧

1.获取View在屏幕上的绝对位置

@Override

protected void onDraw(Canvas canvas) {

float[] values = new float[9];

int[] location1 = new int[2];

Matrix matrix = canvas.getMatrix();

matrix.getValues(values);

location1[0] = (int) values[2];

location1[1] = (int) values[5];

Log.i(TAG, "location1 = " + Arrays.toString(location1));

int[] location2 = new int[2];

this.getLocationOnScreen(location2);

Log.i(TAG, "location2 = " + Arrays.toString(location2));

}

2.利用setPolyToPoly制造3D效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值