构造方法
Matrix ()
Matrix (Matrix src)
基本方法
-
equals()
:比较两个Matrix
的数值是否相同。 -
hashCode()
:获取Matrix
的哈希值。 -
toString()
:将Matrix
转换为字符串:Matrix{[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]}
。 -
toShortString()
:将Matrix
转换为短字符串:[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]
。
数值操作
set
没有返回值,有一个参数,作用是将参数Matrix
的数值复制到当前Matrix
中。如果参数为空,则重置当前Matrix
,相当于reset()
。
void set (Matrix src)
reset
重置当前Matrix
(将当前Matrix
重置为单位矩阵)。
void reset ()
setValues
setValues()
的参数是浮点型的一维数组,长度需要大于9,拷贝数组中的前9位数值赋值给当前Matrix
。
void setValues(float[] values)
getValues
参数是浮点型的一维数组,长度需要大于9,将Matrix
中的数值拷贝进参数的前9位中。
void getValues(float[] values)
数值计算
mapPoints
计算一组点基于当前Matrix
变换后的位置,(由于是计算点,所以参数中的float数组长度一般都是偶数的,若为奇数,则最后一个数值不参与计算)。
void mapPoints(float[] pts)
void mapPoints(float[] dst, float[] src)
void mapPoints(float[] dst, int dstIndex,float[] src, int srcIndex, int pointCount)
方法一
void mapPoints (float[] pts)
方法仅有一个参数,pts
数组作为参数传递原始数值,计算结果仍存放在pts
中。
方法二
void mapPoints (float[] dst, float[] src)
,src
作为参数传递原始数值,计算结果存放在dst
中,src
不变。
方法三
void mapPoints (float[] dst, int dstIndex,float[] src, int srcIndex, int pointCount)
可以指定只计算一部分数值。
参数 | 摘要 |
---|---|
dst | 目标数据 |
dstIndex | 目标数据存储位置起始下标 |
src | 源数据 |
srcIndex | 源数据存储位置起始下标 |
pointCount | 计算的点个数 |
mapRadius
测量半径,由于圆可能会因为画布变换变成椭圆,所以此处测量的是平均半径。
方法
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);
mapRadius: 100.0
mapRadius: 70.71068
mapRect
测量矩形变换后位置,返回值是判断矩形经过变换后是否仍为矩形,非90度倍数的旋转也会变成非矩形。
boolean mapRect(RectF rect)
boolean mapRect(RectF dst, RectF src)
方法一
boolean mapRect (RectF rect)
测量rect
并将测量结果放入rect
中。
方法二
boolean mapRect (RectF dst, RectF src)
测量src
并将测量结果放入dst
中。
mapVectors
测量向量,mapVectors
与 mapPoints
基本上是相同的,可以直接参照上面的mapPoints
使用方法。两者唯一的区别就是mapVectors
不会受到位移的影响,这符合向量的定律。
void mapVectors(float[] vecs)
void mapVectors(float[] dst, float[] src)
void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int vectorCount)
set、pre 与 post
方法 | 简介 |
---|---|
set | 设置,会覆盖掉之前的数值,导致之前的操作失效。 |
pre | 前乘,构造矩阵乘式时,往前端压入乘式因子。 |
post | 后乘,构造矩阵乘式时,往后端压入乘式因子。 |
特殊方法
setPolyToPoly
简介
Poly 全称是 Polygon ,多边形的意思。setPolyToPoly()
最多可以支持4个点。
boolean setPolyToPoly (
float[] src, // 原始数组 src [x,y],存储内容为一组点
int srcIndex, // 原始数组开始位置
float[] dst, // 目标数组 dst [x,y],存储内容为一组点
int dstIndex, // 目标数组开始位置
int pointCount) // 测控点的数量 取值范围是: 0到4
pointCount | 摘要 |
---|---|
0 | 相当于reset
|
1 | 可以进行 平移 |
2 | 可以进行 缩放、旋转、平移 变换 |
3 | 可以进行 缩放、旋转、平移、错切 变换 |
4 | 可以进行 缩放、旋转、平移、错切以及任何形变 |
示例
public class MatrixSetPolyToPolyTest extends View {
private Bitmap mBitmap; // 要绘制的图片
private Matrix mPolyMatrix; // 测试setPolyToPoly用的Matrix
public MatrixSetPolyToPolyTest(Context context) {
super(context);
initBitmapAndMatrix();
}
private void initBitmapAndMatrix() {
mBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.poly_test);
mPolyMatrix = new Matrix();
float[] src = {0, 0, // 左上
mBitmap.getWidth(), 0, // 右上
mBitmap.getWidth(), mBitmap.getHeight(), // 右下
0, mBitmap.getHeight()}; // 左下
float[] dst = {0, 0, // 左上
mBitmap.getWidth(), 400, // 右上
mBitmap.getWidth(), mBitmap.getHeight() - 200, // 右下
0, mBitmap.getHeight()}; // 左下
// 核心要点
mPolyMatrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1); // src.length >> 1 为位移运算 相当于处以2
// 此处为了更好的显示对图片进行了等比缩放和平移(图片本身有点大)
mPolyMatrix.postScale(0.26f, 0.26f);
mPolyMatrix.postTranslate(0,200);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 根据Matrix绘制一个变换后的图片
canvas.drawBitmap(mBitmap, mPolyMatrix, null);
}
}
pointCount为0
pointCount()
为0
和reset()
是等价的。
pointCount为1
pointCount()
为1
和translate
是等价的,平移的距离是dst - src
。
pointCount为2
当pointCount
为2
的时候,可以做缩放、平移和旋转。
pointCount为3
当pointCount
为3
的时候,可以做缩放、平移、旋转和错切。
pointCount为4
当pointCount
为4
的时候,你可以将图像拉伸为任意四边形。
setRectToRect
简介
将源矩形的内容填充到目标矩形中。
boolean setRectToRect (RectF src, // 源区域
RectF dst, // 目标区域
Matrix.ScaleToFit stf) // 缩放适配模式
Matrix.ScaleToFit
:
模式 | 摘要 |
---|---|
CENTER | 居中,对src等比例缩放,将其居中放置在dst中。 |
START | 顶部,对src等比例缩放,将其放置在dst的左上角。 |
END | 底部,对src等比例缩放,将其放置在dst的右下角。 |
FILL | 充满,拉伸src的宽和高,使其完全填充满dst。 |
图示
src(原始状态) | |
---|---|
CENTER | |
START | |
END | |
FILL |
示例
展示居中例子:
public class MatrixSetRectToRectTest extends View {
private static final String TAG = "MatrixSetRectToRectTest";
private int mViewWidth, mViewHeight;
private Bitmap mBitmap; // 要绘制的图片
private Matrix mRectMatrix; // 测试etRectToRect用的Matrix
public MatrixSetRectToRectTest(Context context) {
super(context);
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.rect_test);
mRectMatrix = new Matrix();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mViewWidth = w;
mViewHeight = h;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
RectF src= new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight() );
RectF dst = new RectF(0, 0, mViewWidth, mViewHeight );
// 核心要点
mRectMatrix.setRectToRect(src,dst, Matrix.ScaleToFit.CENTER);
// 根据Matrix绘制一个变换后的图片
canvas.drawBitmap(mBitmap, mRectMatrix, new Paint());
}
}
rectStaysRect
判断矩形经过变换后是否仍为矩形,假如Matrix
进行了平移、缩放则画布仅仅是位置和大小改变,矩形变换后仍然为矩形,但Matrix
进行了非90度倍数的旋转或者错切,则矩形变换后就不再是矩形了。
setSinCos
简介
设置sinCos
值,这个是控制Matrix
旋转的,由于Matrix
已经封装好了Rotate方法,所以这个并不常用。
// 方法一
void setSinCos (float sinValue, // 旋转角度的sin值
float cosValue) // 旋转角度的cos值
// 方法二
void setSinCos (float sinValue, // 旋转角度的sin值
float cosValue, // 旋转角度的cos值
float px, // 中心位置x坐标
float py) // 中心位置y坐标
示例
Matrix matrix = new Matrix();
// 旋转90度
// sin90=1
// cos90=0
matrix.setSinCos(1f, 0f);
Log.i(TAG, "setSinCos:"+matrix.toShortString());
// 重置
matrix.reset();
// 旋转90度
matrix.setRotate(90);
Log.i(TAG, "setRotate:"+matrix.toShortString());
setSinCos:[0.0, -1.0, 0.0][1.0, 0.0, 0.0][0.0, 0.0, 1.0]
setRotate:[0.0, -1.0, 0.0][1.0, 0.0, 0.0][0.0, 0.0, 1.0]
矩阵相关
方法 | 摘要 |
---|---|
invert | 求矩阵的逆矩阵 |
isAffine | 判断当前矩阵是否为仿射矩阵,API21(5.0)才添加的方法。 |
isIdentity | 判断当前矩阵是否为单位矩阵。 |
invert
求矩阵的逆矩阵,简而言之就是计算与之前相反的矩阵,如果之前是平移200px
,则求的矩阵为反向平移200px
,如果之前是缩小到0.5f
,则结果是放大到2
倍。
boolean invert(Matrix inverse)
isAffine
判断是否是仿射矩阵最重要的一点就是,直线是否仍为直线,简单想一下就知道,不论平移,旋转,错切,缩放,直线变换后最终仍为直线,要想让isAffine()
的结果变为false
,除非你能把直线掰弯。
boolean isAffine()
isIdentity
判断是否为单位矩阵。
实用技巧
获取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));
}
location1 = [0, 243]
location2 = [0, 243]
利用setPolyToPoly制造3D效果
Android FoldingLayout 折叠布局 原理及实现(一)
Android FoldingLayout 折叠布局 原理及实现(二)