Camera 在自定义view中的使用


1.关于Matrix

在andorid中是一个三维矩阵

{  
                MSCALE_X, MSKEW_X, MTRANS_X,    
                MSKEW_Y, MSCALE_Y, MTRANS_Y,    
                MPERSP_0, MPERSP_1, MPERSP_2    
};  

matrix提供了一系列的api,实质上是对着9个数据的操作。


博客参考:http://blog.csdn.net/linmiansheng/article/details/18820599

                  http://www.gcssloop.com/customview/Matrix_Basic

                  http://www.jianshu.com/p/5eaa81c22d17

                  http://blog.csdn.net/csxiaoshui/article/details/65446125





这篇文章写得很赞:

地址:https://github.com/xingstarx/AndroidNote/blob/master/view/Matrix%E8%AF%A6%E8%A7%A3.md#%E9%83%A8%E5%88%86%E7%96%91%E9%97%AE%E8%A7%A3%E8%AF%BB

#Android Matrix深入理解

##Android中的Matrix类

类的主要结构

public class Matrix {
    public static final int MPERSP_0 = 6;
    public static final int MPERSP_1 = 7;
    public static final int MPERSP_2 = 8;
    public static final int MSCALE_X = 0;
    public static final int MSCALE_Y = 4;
    public static final int MSKEW_X = 1;
    public static final int MSKEW_Y = 3;
    public static final int MTRANS_X = 2;
    public static final int MTRANS_Y = 5;
    ...
}

Matrix类转换为3*3矩阵的表现形式为(由于不太懂矩阵的markdown语法,就用表格表示吧)

0 1 2
MSCALE_X MSKEW_X MTRANS_X
MSKEW_Y MSCALE_Y MTRANS_Y
MPERSP_0 MPERSP_1 MPERSP_2

##Matrix常用API

Matrix操作方法主要分为三类,分别是set,post,pre三类,其中set不用多讲,prepost则不一样,代表着不同的矩阵乘法顺序

我们用translate来讲

setTranslate() 指定了移动的位置,不需要通过左乘右乘

postTranslate() 在方法内部进行的是 M' = T(dx, dy) * M,t 左乘m

preTranslate() 在方法内部进行的是 M' = M * T(dx, dy),m左乘t

post,pre的乘法计算顺序是相反的,矩阵乘法不满足交换律,所以计算结果几乎是不同的。

常用API包括下面的组合形式

  set pre post
translate setTranslate preTranslate postTranslate
scale setScale preScale postScale
rotate setRotate preRotate postRotate

以及其他常用API

setConcat()

##数学知识 1 矩阵乘法(3*3相乘)

0 1 2 * 0 1 2
a0 a1 a2   b0 b1 b2
a3 a4 a5   b3 b4 b5
a6 a7 a8   b6 b7 b8

========>

0 1 2
a0b0+a1b3+a2b6 a0b1+a1b4+a2b7 a0b2+a1b5+a2b8
a3b0+a4b3+a5b6 a3b1+a4b4+a5b7 a3b2+a4b5+a5b8
a6b0+a7b3+a8b6 a6b1+a7b4+a8b7 a6b2+a7b5+a8b8

2 矩阵满足结合律,不满足交换律

3 下列矩阵

0 1 2
1 0 0
0 1 0
0 0 1

为单位矩阵E,单位矩阵E跟其他矩阵T做乘法操作,得到的结果都是其他矩阵T,Android中通过new Matrix(),或者是reset方法得到的都是单位矩阵E

##部分疑问解读

###案例1

matrix.preScale(0.5f, 0.5f);
matrix.preTranslate(-pivotX, -pivotY);
matrix.postTranslate(pivotX, pivotY);

这段代码执行的结果是什么呢?我们假设当前的屏幕是720*1280px,屏幕密度为2,在我的红米2A上就是这个数据,同时我也以这个数据做实验。假设pivotX为屏幕宽度的一半,pivotY为屏幕高度的一半,pivotX = 360, pivotY = 640

Matrix(m)初始化的值为(对于执行了new Matrix()或者是reset()的都是下面的矩阵)

0 1 2
1 0 0
0 1 0
0 0 1

第一行的执行过程

matrix.preScale(0.5f, 0.5f)

左乘 m * s

M' = M * S(sx, sy)

0 1 2   0 1 2
1 0 0 * 0.5 0 0
0 1 0   0 0.5 0
0 0 1   0 0 1

结果m变成了下面的结果

0 1 2
0.5 0 0
0 0.5 0
0 0 1

第二行执行过程

接着m在进行preTranslate (-360, -640)运算

M' = M * T(dx, dy)

0 1 2   0 1 2
0.5 0 0 * 1 0 -360
0 0.5 0   0 1 -640
0 0 1   0 0 1

结果是m变成了

0 1 2
0.5 0 -180
0 0.5 -320
0 0 1

第三行执行过程

这一步乘法的顺序跟前两步是不一样的

postTranslate(360, 640)

M' = T(dx, dy) * M

0 1 2   0 1 2
1 0 360 * 0.5 0 -180
0 1 640   0 0.5 -320
0 0 1   0 0 1

结果变成了

0 1 2
0.5 0 180
0 0.5 320
0 0 1

那么这三行代码执行的结果,解释起来就是沿着view的中心位置缩放一半



很厉害的一篇博客:http://www.gcssloop.com/customview/matrix-3d-camera


博客中的一些注意事项:

摄像机

如果你学过Unity,那么你对摄像机这一个概念应该会有比较透彻的理解。在一个虚拟的3D的立体空间中,由于我们无法直接用眼睛去观察这一个空间,所以要借助摄像机采集信息,制成2D影像供我们观察。简单来说,摄像机就是我们观察虚拟3D空间的眼睛

Android 上面观察View的摄像机默认位置在屏幕左上角,而且是距屏幕有一段距离的


view(博客中的图片)在屏幕中间,centerX,centerY为屏幕的中心点

Matrix temp = new Matrix();		// 临时Matrix变量
this.getMatrix(temp);			// 获取Matrix
temp.preTranslate(-centerX, -centerY);	// 使用pre将旋转中心移动到和Camera位置相同。
temp.postTranslate(centerX, centerY);	// 使用post将图片(View)移动到原来的位置


1使用pre将旋转中心移动到和Camera位置相同
解释:3D效果的呈现主要是借助camera,camera的位置是很重要的(在view正前方,不在正前方(在旁边)),camera的默认位置在
屏幕的左上角,所以先将view和camera放置在同一条直线上(将view的中心移动到左上角,就相当于我们在正前方观察东西)
2使用post将图片(View)移动到原来的位置
解释:上一步将图片中心移动到了左上角,这步再将图片恢复到原位置上。


啊啊啊啊啊啊。这个camera到底是在view左上角还是屏幕左上角啊啊啊啊啊啊啊啊啊啊啊啊啊啊?

你可能感兴趣的:(Android自定义控件)