Matrix中set/post/per區別

1、setScale(sx,sy),首先會將該Matrix設置爲對角矩陣,即相當於調用reset()方法,然後在設置該Matrix的MSCALE_X和MSCALE_Y直接設置爲sx,sy的值 

2、preScale(sx,sy),不會重置Matrix,而是直接與Matrix之前的MSCALE_X和MSCALE_Y值結合起來(相乘),M' = M * S(sx, sy)。

3、postScale(sx,sy),不會重置Matrix,而是直接與Matrix之前的MSCALE_X和MSCALE_Y值結合起來(相乘),M' = S(sx, sy) * M。

preScale和post都是與之前的Matrix結合起來,那它們之間又有什麼區別呢?

舉幾個例子測試下關於pre....和post....的區別:

對一個Matrix如下設置

1、pre....的執行順序

Matrix matrix=new Matrix();
        float[] points=new float[]{10.0f,10.0f};
        
        matrix.preScale(2.0f, 3.0f);//
        matrix.preTranslate(8.0f,7.0f);//
        matrix.mapPoints(points);
        Log.i("test", points[0]+"");
        Log.i("test", points[1]+"");

結果爲點座標爲(36.0,51.0)

可以得出結論,進行變換的順序是先執行preTranslate(8.0f,7.0f),在執行的preScale(2.0f,3.0f)。這也是爲什麼有的人比喻爲pre...是向後生長的,即對於一個Matrix的設置中,

所有pre....是倒着向後執行的。


2、post...的執行順序 

Matrix matrix=new Matrix();
        float[] points=new float[]{10.0f,10.0f};
        
        matrix.postScale(2.0f, 3.0f);//
        matrix.postTranslate(8.0f,7.0f);//
        matrix.mapPoints(points);
        Log.i("test", points[0]+"");
        Log.i("test", points[1]+"");

結果爲點座標爲(28.0,37.0)

可以得出結論,進行變換的順序是先執行postScale(2.0f,3.0f),在執行的postTranslate(8.0f,7.0f)。這也是爲什麼有的人比喻爲post...是向前生長的,即對於一個Matrix的設置中,所有post....是順着向前執行的。


3、當pre和post交替出現的執行順序 

Matrix matrix=new Matrix();
        float[] points=new float[]{10.0f,10.0f};

        matrix.postScale(2.0f, 3.0f);
        matrix.preRotate(90);
        matrix.mapPoints(points);
        Log.i("test", points[0]+"");
        Log.i("test", points[1]+"");
結果爲點座標爲(-20.0,30.0) 

將pre...和post順序換一下

Matrix matrix=new Matrix();
        float[] points=new float[]{10.0f,10.0f};
        
        matrix.preRotate(90);
        matrix.postScale(2.0f, 3.0f);
        matrix.mapPoints(points);
        Log.i("test", points[0]+"");
        Log.i("test", points[1]+"");
結果爲點座標依舊爲爲(-20.0,30.0) 

可見,總是pre先執行的。在看下面的:
Matrix matrix = new Matrix();
    float[] points = new float[] { 10.0f, 10.0f };

    matrix.postScale(2.0f, 3.0f);// 第1步
    matrix.preRotate(90);// 第2步
    matrix.postTranslate(8.0f, 7.0f);// 第3步
    matrix.preScale(1.5f, 2.5f);// 第4步
    matrix.mapPoints(points);
    Log.i("test", points[0] + "");
    Log.i("test", points[1] + "");
結果爲點座標依舊爲爲(-42.0,52.0) 
經過前面的結論和推算,可以發現執行的順序是   4----2----1---3 


 在看下面的,增加了setScale的一段代碼:

Matrix matrix = new Matrix();
    float[] points = new float[] { 10.0f, 10.0f };

    matrix.postScale(2.0f, 3.0f);// 第1步
    matrix.preRotate(90);// 第2步
    matrix.setScale(1.4f, 2.6f);// 第3步
    matrix.postTranslate(8.0f, 7.0f);// 第4步
    matrix.preScale(1.5f, 2.5f);// 第5步
    matrix.mapPoints(points);
    Log.i("test", points[0] + "");
    Log.i("test", points[1] + "");
結果爲點座標依舊爲爲(29.0,72.0) 
經過計算,可以發現,在第3步setScale之前的第1、2步根本就沒有用了,直接被第3步setScale覆蓋,在從第3開始執行的。

順序爲2---1----3----5----4,因爲2、1被覆蓋了,所以沒有效果,相當於直接執行3-----5----4


總結:最後可以得出結論,在對matrix該次變換之前的所有設置中,先檢測有沒有setScale,如果有,直接跳到setScale那一步開始執行變換,然後在倒着執行下面所有的pre...變換,在順着執行所有post....的變換。所以在對Matrix變換設置的時候,一定要注意順序,不同的順序,會有不同的結果。 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章