一、簡介
Android android.graphics.Matrix
類是一個3 x 3的矩陣(方陣),上一張幾乎所有介紹Matrix的文章都會引用的Matrix內容圖:

二、相關方法
1、equals
比較兩個矩陣是否相等。
Matrix matrix1 = new Matrix(); Matrix matrix2 = new Matrix(); matrix1.setTranslate(1,2); matrix2.setTranslate(2,2); // 輸出:matrix1 == matrix2:false System.out.println("matrix1 == matrix2:" + matrix1.equals(matrix2));
2、+號相連/toString/toShortString
將矩陣轉換為字符串。
Matrix matrix = new Matrix(); // 輸出:+號相連:Matrix{[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]} System.out.println("+號相連:" + matrix); // 輸出:Matrix{[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]} System.out.println("toString:" + matrix.toString()); // 輸出:[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0] System.out.println("toShortString:" + matrix.toShortString());
3、getValues()、setValues()
當我們調用Matrix類的getValues(float[] values)、setValues(float[] values)
方法時,可以將這個矩陣轉換成一個數組進行操作。轉換后的數組為:
[ MSCALE_X, MSKEW_X, MTRANS_X, MSKEW_Y, MSCALE_Y, MTRANS_Y, MPERSP_0, MPERSP_1, MPERSP_2]
為了方便操作這個數組,在android.graphics.Matrix
類中,定義了MSCALE_X、MSKEW_X...變量,分別代表各自功能在數組中對應的下標,具體內容如下:
public static final int MSCALE_X = 0; //!< use with getValues/setValues public static final int MSKEW_X = 1; //!< use with getValues/setValues public static final int MTRANS_X = 2; //!< use with getValues/setValues public static final int MSKEW_Y = 3; //!< use with getValues/setValues public static final int MSCALE_Y = 4; //!< use with getValues/setValues public static final int MTRANS_Y = 5; //!< use with getValues/setValues public static final int MPERSP_0 = 6; //!< use with getValues/setValues public static final int MPERSP_1 = 7; //!< use with getValues/setValues public static final int MPERSP_2 = 8; //!< use with getValues/setValues
方法示例:
Matrix matrix = new Matrix(); // matrix = [1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0] System.out.println("matrix = " + matrix.toShortString()); float[] values = new float[9]; matrix.getValues(values); // matrix轉換成數組后 = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] System.out.println("matrix轉換成數組后 = " + Arrays.toString(values)); // 為matrix賦值 values [Matrix.MTRANS_X] = 2; values [Matrix.MTRANS_Y] = 3; matrix.setValues(values); // matrix = [1.0, 0.0, 2.0][0.0, 1.0, 3.0][0.0, 0.0, 1.0] System.out.println("matrix = " + matrix.toShortString());
4、setXXX/preXXX/postXXX
XXX可以是Translate、Scale、Rotate、Skew和Concat。其中Concat參數為Matrix,表示直接操作Matrix。由於縮放、旋轉、錯切可以繞中心操作,如果指定了中心,則變換步驟為:
- 將原點平移到該點。
- 做縮放、錯切、旋轉操作。
- 原點平移到原來的原點處。
方法參數轉換成了一個怎樣的矩陣?
// 下面代碼中參數(2,2) 轉換后的矩陣為 // [2.0, 0.0, 0.0] // [0.0, 2.0, 0.0] // [0.0, 0.0, 1.0] // 即根據XXX代表的功能修改矩陣中對應功能位置的值即可 matrix.postScale(2,2);
setXXX
首先會將該Matrix重置為單位矩陣,即相當於首先會調用reset()方法,然后再設置該Matrix中對應功能的值。例:
// [1.0, 0.0, 0.0] // [0.0, 1.0, 0.0] // [0.0, 0.0, 1.0] Matrix matrix = new Matrix(); // [1.0, 0.0, 0.0] [2.0, 3.0, 4.0] // [0.0, 1.0, 0.0] -> [2.0, 0.0, 0.0] // [0.0, 0.0, 1.0] [1.0, 1.0, 1.0] matrix.setValues(new float[]{2.0f,3.0f, 4.0f, 2.0f,0.0f, 0.0f, 1.0f,1.0f,1.0f}); // [2.0, 3.0, 4.0] [1.0, 0.0, 0.0] [2.0, 0.0, 0.0] // [2.0, 2.0, 0.0] -> [0.0, 1.0, 0.0] -> [0.0, 2.0, 0.0] // [1.0, 1.0, 1.0] [0.0, 0.0, 1.0] [0.0, 0.0, 1.0] matrix.setScale(2,2);
preXXX
不會重置Matrix,相當於當前操作矩陣(A)左乘參數矩陣(B),即AB。例:
// [1.0, 0.0, 0.0] // [0.0, 1.0, 0.0] // [0.0, 0.0, 1.0] Matrix matrix = new Matrix(); // [1.0, 0.0, 0.0] [2.0, 3.0, 4.0] // [0.0, 1.0, 0.0] -> [2.0, 0.0, 0.0] // [0.0, 0.0, 1.0] [1.0, 1.0, 1.0] matrix.setValues(new float[]{2.0f,3.0f, 4.0f, 2.0f,0.0f, 0.0f, 1.0f,1.0f,1.0f}); // [2.0, 3.0, 4.0] [2.0, 0.0, 0.0] [4.0, 6.0, 4.0] // [2.0, 0.0, 0.0](matrix) * [0.0, 2.0, 0.0] = [4.0, 0.0, 0.0](matrix) // [1.0, 1.0, 1.0] [0.0, 0.0, 1.0] [2.0, 2.0, 1.0] matrix.preScale(2,2);
postXXX
不會重置Matrix,相當於當前操作矩陣(A)右乘參數矩陣(B),即BA,例:
// [1.0, 0.0, 0.0] // [0.0, 1.0, 0.0] // [0.0, 0.0, 1.0] Matrix matrix = new Matrix(); // [1.0, 0.0, 0.0] [2.0, 3.0, 4.0] // [0.0, 1.0, 0.0] -> [2.0, 0.0, 0.0] // [0.0, 0.0, 1.0] [1.0, 1.0, 1.0] matrix.setValues(new float[]{2.0f,3.0f, 4.0f, 2.0f,0.0f, 0.0f, 1.0f,1.0f,1.0f}); // [2.0, 0.0, 0.0] [2.0, 3.0, 4.0] [4.0, 6.0, 8.0] // [0.0, 2.0, 0.0] * [2.0, 0.0, 0.0] (matrix) = [4.0, 0.0, 0.0](matrix) // [0.0, 0.0, 1.0] [1.0, 1.0, 1.0] [1.0, 1.0, 1.0] matrix.postScale(2,2);
setContact
關於setContact(Matrix m1,Matrix m2)方法,需要單獨說下,它的參數為兩個Matrix對象,計算規則為:當前操作的Matrix對象 = m1 * m2;
例:
// [1.0, 0.0, 0.0] // [0.0, 1.0, 0.0] // [0.0, 0.0, 1.0] Matrix matrix = new Matrix(); Matrix matrix1 = new Matrix(); Matrix matrix2 = new Matrix(); // [1.0, 0.0, 0.0] [2.0, 3.0, 4.0] // [0.0, 1.0, 0.0] -> [2.0, 0.0, 0.0] // [0.0, 0.0, 1.0] [1.0, 1.0, 1.0] matrix1.setValues(new float[]{2.0f,3.0f, 4.0f, 2.0f,0.0f, 0.0f, 1.0f,1.0f,1.0f}); // [1.0, 0.0, 0.0] [2.0, 5.0, 4.0] // [0.0, 1.0, 0.0] -> [3.0, 0.0, 0.0] // [0.0, 0.0, 1.0] [1.0, 2.0, 1.0] matrix2.setValues(new float[]{2.0f,5.0f, 4.0f, 3.0f,0.0f, 0.0f, 1.0f,2.0f,1.0f}); // [2.0, 3.0, 4.0] [2.0, 5.0, 4.0] [17.0, 18.0, 12.0] // [2.0, 2.0, 0.0](matrix1) * [3.0, 0.0, 0.0](matrix2) = [4.0, 10.0, 8.0 ] (matrix) // [1.0, 1.0, 1.0] [1.0, 2.0, 1.0] [6.0, 7.0, 5.0 ] matrix.setConcat(matrix1,matrix2);
5、mapRadius/mapPoints/mapRect/mapVectors
可翻譯為將矩陣映射到(作用於)點、矩形、半徑、向量。
mapRadius
半徑的計算。例:
// 一個半徑為100.0f的圓,放大1倍后,半徑也將增大一倍。據說用在畫布中的圓隨畫布大小變化時 float radius = 100.0f; float radiusAfterMatrix; Matrix matrixRadius = new Matrix(); matrixRadius.setScale(2,2); radiusAfterMatrix = matrixRadius.mapRadius(radius); // 輸出:radius=200.0 System.out.println("radius=" + radiusAfterMatrix);
mapPoints
此方法有3個重載方法。點數組各值分別代表pts[x0,y0,x1,y1 ... xn,yn]
,因為一個點的確定需要x坐標和y坐標兩個值,所以,pts數組的長度一般為偶數,如果為奇數,則最后一個值不參與計算(長度為1將不計算)。下面給出具體例子,例子中將會詳細說明mapPoints方法。
// ======================= // mapPoints(float[] pts) // ======================= // 運算后的結果會保存在pts數組中,原pts數組中的內容會被覆蓋 // 1.《點的移動》,對於任意點(Xn,Yn),x軸方向平移dx,y軸方向平移dy后有: // Xn = Xn + dx // Yn = Yn + dy float[] ptsTrans = {6,2}; Matrix matrixTrans = new Matrix(); matrixTrans.setTranslate(-2,2); matrixTrans.mapPoints(ptsTrans); // 輸出:trans=[4.0, 4.0] System.out.println("trans=" + Arrays.toString(ptsTrans)); // 2.《點的放大》,對於任意點(Xn,Yn),繞點(px,py)x軸、y軸方向分別放大sx倍、sy倍后,有: // Xn = Xn * sx + (px - px * sx) // Yn = Yn * sy + (py - sy * py) float[] ptsScale = {2,3}; Matrix matrixScale = new Matrix(); matrixScale.setScale(3,6,2,2); matrixScale.mapPoints(ptsScale); // 輸出:scale=[2.0, 8.0] System.out.println("scale=" + Arrays.toString(ptsScale)); // 3.《點的旋轉》,對於任意點(Xn,Yn),繞點(px,py)旋轉a度后,有: // Xn = (Xn - px) * cos(a) - (Yn - py) * sin(a) + px // Yn = (Xn - px) * sin(a) + (Yn - py) * cos(a) + py float[] ptsRotate = {6,6}; Matrix matrixRotate = new Matrix(); matrixRotate.preRotate(90,2,3); matrixRotate.mapPoints(ptsRotate); // 輸出:rotate=[-1.0,7.0] System.out.println("rotate=" + Arrays.toString(ptsRotate)); // 4.《點的錯切》,對於任意點(Xn,Yn),繞點(px,py)x軸、y軸方向分別錯切kx、ky后,有: // Xn = Xn + kx(Yn - py) // Yn = Yn + ky(Xn - px) float[] ptsSkew = {3,2}; Matrix matrixSkew = new Matrix(); matrixSkew.setSkew(2,3,6,8); matrixSkew.mapPoints(ptsSkew); // 輸出:skew=[-9.0,-7.0] System.out.println("skew=" + Arrays.toString(ptsSkew)); // =================================== // mapPoints(float[] dst, float[] src) // =================================== // 運算后的結果保存在dst數組中,原src數組中的內容會保留 float[] src = {2,3,3,3}; float[] dst = new float[src.length]; Matrix matrixDstSrc = new Matrix(); matrixDstSrc.setTranslate(2,3