Android矩阵变换讲解Matrix

        在二维的平面上,对图片进行处理时,主要可以分为平移,缩放和旋转,如果是直接对图片坐标进行处理显然是很复杂的,这是我们就可以用到矩阵,在矩阵中有单位矩阵这么个概念,我的理解就是这是一个标准的坐标系,其他的变换都是基于这个坐标来的,可能理解有出入,不过这我能想到跟实际相关联的。

        下面先来看看2D图形变换中的

        平移:

        我们先假设平面上有一点(x,y),这个点向x,y方向上平移了dx,dy,变换后的坐标(X,Y)=(x+dx,y+dy),用矩阵表示:

  1 0 dx   x     X                               1 0 dx
[ 0 1 dy ][y] = [Y] 我们可以发现平移变换矩阵是: [0 1 dy]
  0 0 1    1     1                               0 0 1

        缩放:

        同样的假设平面上一点坐标(x,y),在x,y方向上缩放了sx,sy,变换后的坐标(X,Y)=(sx*x,sy*y),用矩阵表示:

  sx 0  0   x     X                               sx 0  0
[ 0  sy 0 ][y] = [Y] 我们可以发现缩放变换矩阵是: [0  sy 0]
  0  0  1   1     1                               0  0  1

        旋转:

        旋转稍微复杂一点,不过先同样假设一点坐标(x,y)到原点的坐标是R,到x轴的坐标是β,以原点为圆心,旋转θ度,那么变换后的坐标是:x=R*cosβ,y=R*sinβ,X=Rcos(β+θ),Y=sin(β+θ),对X,Y进行合角公式变换:

X=R*cosβ*cosθ-R*sinβ*sinθ=x*cosθ-y*sinθ

Y=R*sinβ*cosθ+R*cosβ*sinθ=y*cosθ+x*sinθ,用矩阵表示:

  cosθ -sinθ 0   x     X                               cosθ -sinθ  0
[ sinθ  cosθ 0 ][y] = [Y] 我们可以发现旋转变换矩阵是: [sinθ  cosθ  0]
  0      0     1   1     1                                 0     0     1

根据我自己的理解,矩阵就是坐标系,单位矩阵就是标准坐标系,对于二维平面,可以用3x3的单位矩阵表示。对于矩阵的理解(限于二维平面):第一行我理解是x的变换,第二行理解为y的变换,第三行就是常数了,正好与上面的对应上。对于矩阵的变换其实就是对坐标系的变换,不知道是不是可以这样去理解。

        接下来看看Android中Matrix是如何变换的:先看Android是如何描述这个类的:

* The Matrix class holds a 3x3 matrix for transforming coordinates.

        解释:矩阵类用一个3x3的矩阵对坐标进行转换。(方法基本都是native的,就没必要看源码了)

        来看看Matrix是如何作用的:

    private void initMatrix(){
        float[] arr = {1,0,0,
                       0,1,0,
                       0,0,1};
        StringBuilder builder = new StringBuilder();
        Matrix matrix = new Matrix();
        matrix.setValues(arr);
        matrix.setTranslate(2,2);
//        matrix.setScale(2,2);
//        matrix.setRotate((float) Math.toDegrees(Math.PI/3));
        matrix.getValues(arr);
        builder.append("{");
        for (float v : arr) {
            builder.append(v+",");
        }
        builder.append("}");
        Log.d(TAG, "initMatrix: arr = "+builder);
    }

 输出结果(三次分别输出,与上面设置的方法对应):

initMatrix: arr = {1.0,0.0,2.0,
                   0.0,1.0,2.0,
                   0.0,0.0,1.0,}
initMatrix: arr = {2.0,0.0,0.0,
                   0.0,2.0,0.0,
                   0.0,0.0,1.0,}
initMatrix: arr = {0.49999997,-0.86602545,0.0,
                   0.86602545,0.49999997, 0.0,
                   0.0,       0.0,        1.0,}

转换后是不是就和上面是一样了,可以好好体会下。这个还是比较抽象的,不过理解了就比较简单了。

        上面我们得到了一个转换矩阵,现在我们就用这个矩阵来转换一个矩形,看看矩形有什么变化:

    private void initMatrix(){
        float[] arr = {1,0,0,
                       0,1,0,
                       0,0,1};
        StringBuilder builder = new StringBuilder();
        Matrix matrix = new Matrix();
        matrix.setValues(arr);
//        matrix.setTranslate(2,2);
        matrix.setScale(2,2);
//        matrix.setRotate((float) Math.toDegrees(Math.PI/3));
        RectF rect = new RectF();
        rect.set(0,0,6,6);
        matrix.mapRect(rect);
        Log.d(TAG, "initMatrix: rect = "+rect.left+"   "+rect.top+"   "+rect.right+"   "+rect.bottom);
        matrix.getValues(arr);
        builder.append("{");
        for (float v : arr) {
            builder.append(v+",");
        }
        builder.append("}");
        Log.d(TAG, "initMatrix: arr = "+builder.toString());
    }

输出结果(三次分别输出,与上面设置的方法对应),主要是看矩形输出结果:

initMatrix: rect = 2.0   2.0   8.0   8.0
initMatrix: rect = 0.0   0.0   12.0   12.0
initMatrix: rect = -5.1961527   0.0   2.9999998   8.196153
如果这个矩形是一个图片,那这样变换就是图片的变换了。



猜你喜欢

转载自blog.csdn.net/tangedegushi/article/details/80520523