Camera 在自定义view中的使用

本文深入剖析了Android中的Matrix类,详细介绍了其内部结构及常用API,如translate、scale、rotate等方法,并通过具体案例展示了如何利用Matrix实现视图的平移、缩放与旋转。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


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.youkuaiyun.com/linmiansheng/article/details/18820599

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

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

                  http://blog.youkuaiyun.com/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语法,就用表格表示吧)

012
MSCALE_XMSKEW_XMTRANS_X
MSKEW_YMSCALE_YMTRANS_Y
MPERSP_0MPERSP_1MPERSP_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包括下面的组合形式

 setprepost
translatesetTranslatepreTranslatepostTranslate
scalesetScalepreScalepostScale
rotatesetRotatepreRotatepostRotate

以及其他常用API

setConcat()

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

012*012
a0a1a2 b0b1b2
a3a4a5 b3b4b5
a6a7a8 b6b7b8

========>

012
a0b0+a1b3+a2b6a0b1+a1b4+a2b7a0b2+a1b5+a2b8
a3b0+a4b3+a5b6a3b1+a4b4+a5b7a3b2+a4b5+a5b8
a6b0+a7b3+a8b6a6b1+a7b4+a8b7a6b2+a7b5+a8b8

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

3 下列矩阵

012
100
010
001

为单位矩阵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()的都是下面的矩阵)

012
100
010
001

第一行的执行过程

matrix.preScale(0.5f, 0.5f)

左乘 m * s

M' = M * S(sx, sy)

012 012
100*0.500
010 00.50
001 001

结果m变成了下面的结果

012
0.500
00.50
001

第二行执行过程

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

M' = M * T(dx, dy)

012 012
0.500*10-360
00.50 01-640
001 001

结果是m变成了

012
0.50-180
00.5-320
001

第三行执行过程

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

postTranslate(360, 640)

M' = T(dx, dy) * M

012 012
10360*0.50-180
01640 00.5-320
001 001

结果变成了

012
0.50180
00.5320
001

那么这三行代码执行的结果,解释起来就是沿着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左上角还是屏幕左上角啊啊啊啊啊啊啊啊啊啊啊啊啊啊?


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值