Matrix矩阵的基础案例与分析
使用Matrix矩阵进行矩形的绘制,进而属性matrix的使用方式,深入了解matrix的原理。
//1、使用默认的Matrix,绘制默认状态的矩形,宽高都是50像素
Rect rect = new Rect(0, 0, 50, 50);
//将Matrix矩阵设置给canvas,并绘制矩形
canvas.setMatrix(mScaleMatrix);
canvas.drawRect(rect,paint);
图-1
//2、平移到屏幕的中心
Rect rect = new Rect(0, 0, 50, 50);
mScaleMatrix.postTranslate(getWidth()/2,getHeight()/2);//图-2
//由于Matrix的原始坐标原点在0,0,所以矩形的左上角与屏幕中心点重合,如果要想矩形的中心与屏幕的中心重合
//需要算上矩形的中心坐标,mScaleMatrix.postTranslate(getWidth()/2-25,getHeight()/2-25);
//在平移至屏幕中心点后,减去矩形一半的平移量.图-2-1
//将Matrix矩阵设置给canvas,并绘制矩形
canvas.setMatrix(mScaleMatrix);
canvas.drawRect(rect,paint);
图-2
图-2-1
//3、缩放
//在默认位置放大2倍
Rect rect = new Rect(0, 0, 50, 50);
mScaleMatrix.postScale(2,2);
//将Matrix矩阵设置给canvas,并绘制矩形
canvas.setMatrix(mScaleMatrix);
canvas.drawRect(rect,paint);
图-3
//4、平移+缩放
//以屏幕中心点为中心放大2倍---错误的做法
Rect rect = new Rect(0, 0, 50, 50);
mScaleMatrix.postScale(2,2,getWidth()/2,getHeight()/2);
Log.i(TAG,mScaleMatrix.toShortString());
//[2.0, 0.0, -540.0][0.0, 2.0, -792.0][0.0, 0.0, 1.0]
float[] values = new float[9];
mScaleMatrix.getValues(values);
Log.i(TAG,"X:平移量:"+values[Matrix.MTRANS_X]);
Log.i(TAG,"Y:平移量:"+values[Matrix.MTRANS_Y]);
Log.i(TAG,"屏幕的高:"+getHeight());
Log.i(TAG,"屏幕的宽:"+getWidth());
//X:平移量:-540.0
//Y:平移量:-792.0
//将Matrix矩阵设置给canvas,并绘制矩形
canvas.setMatrix(mScaleMatrix);
canvas.drawRect(rect,paint);
//如图-4,根本看不到那个矩形,原因已经在注释中说明了,上面的代码会导致矩形反向平移出屏幕,所以根本看不到。
//正确的做法:先平移,在以平移后的中心点进行缩放,才能达到效果
mScaleMatrix.postTranslate(getWidth()/2,getHeight()/2);
mScaleMatrix.postScale(2,2,getWidth()/2,getHeight()/2);
//图4-1
图-4
图4-1
//5、旋转
//以0,0起始坐标点旋转45度
Rect rect = new Rect(0, 0, 50, 50);
mScaleMatrix.postRotate(45);
//将Matrix矩阵设置给canvas,并绘制矩形
canvas.setMatrix(mScaleMatrix);
canvas.drawRect(rect,paint);//图-5
图-5
//6、平移+旋转
//以屏幕中心点,旋转45度
Rect rect = new Rect(0, 0, 50, 50);
mScaleMatrix.postTranslate(getWidth()/2,getHeight()/2);
mScaleMatrix.postRotate(45,getWidth()/2,getHeight()/2);
//将Matrix矩阵设置给canvas,并绘制矩形
canvas.setMatrix(mScaleMatrix);
canvas.drawRect(rect,paint);//图-6
图-6
//7、平移+旋转,看pre 和post的区别,结果都是 图-7
// //方法一:
// //以屏幕中心点,旋转45度
// Rect rect = new Rect(0, 0, 50, 50);
// mScaleMatrix.postTranslate(getWidth()/2,getHeight()/2);
// mScaleMatrix.postRotate(45,getWidth()/2,getHeight()/2);
// //方法二:
// //以屏幕中心点,旋转45度
// Rect rect = new Rect(0, 0, 50, 50);
// mScaleMatrix.postRotate(45);
// mScaleMatrix.postTranslate(getWidth()/2,getHeight()/2);
// //方法三:
// //以屏幕中心点,旋转45度
// Rect rect = new Rect(0, 0, 50, 50);
// mScaleMatrix.preRotate(45);
// mScaleMatrix.postTranslate(getWidth()/2,getHeight()/2);
//方法四:
//以屏幕中心点,旋转45度
Rect rect = new Rect(0, 0, 50, 50);
mScaleMatrix.preRotate(30, getWidth() / 2, getHeight() / 2);
Log.i(TAG,mScaleMatrix.toShortString());
mScaleMatrix.preTranslate(getWidth() / 2, getHeight() / 2);
Log.i(TAG,mScaleMatrix.toShortString());
//preXXXX:以pre开头,例如preTranslate postXXXX:以post开头,例如postScale
//post-前乘或者叫左乘
//pre-后乘或者叫右乘
//如果平移和旋转后结果不是预想的,需要注意上述操作的矩阵结果,打印出来一看便知
//看源码-以平移为例
/**
* Preconcats the matrix with the specified translation. M' = M * T(dx, dy)
public boolean preTranslate(float dx, float dy) {
nPreTranslate(native_instance, dx, dy);
return true;
}*/
/**
* Postconcats the matrix with the specified translation. M' = T(dx, dy) * M
public boolean postTranslate(float dx, float dy) {
nPostTranslate(native_instance, dx, dy);
return true;
}*/
//将Matrix矩阵设置给canvas,并绘制矩形
canvas.setMatrix(mScaleMatrix);
canvas.drawRect(rect, paint);
图-7