camera、Matrix概念

来源:互联网 发布:网页数据分析工具 编辑:程序博客网 时间:2024/05/21 17:36

camera

camera的坐标系是左手坐标系。伸出左手,让拇指和食指成L形,大拇指向右,食指向上,中指指向前方,这样我们就建立了一个左手坐标系,拇指,食指,中指的指向分别代表了x,y,z轴的正方向。如下图所示:

Camera的坐标系是左手坐标系。当手机平整的放在桌面上,X轴是手机的水平方向,Y轴是手机的竖直方向,Z轴是垂直于手机向里的那个方向。

下面是一些细节点:
1,camera位于坐标点(0,0),也就是视图的左上角;
2,camera.translate(10, 20, 30)的意思是把观察物体右移10,上移20,向前移30(即让物体远离camera,这样物体将会变小);
3,camera.rotateX(45)的意思是绕x轴顺时针旋转45度。举例来说,如果物体中间线和x轴重合的话,绕x轴顺时针旋转45度就是指物体上半部分向里翻转,下半部分向外翻转;
4,camera.rotateY(45)的意思是绕y轴顺时针旋转45度。举例来说,如果物体中间线和y轴重合的话,绕y轴顺时针旋转45度就是指物体右半部分向里翻转,左半部分向外翻转;
5,camera.rotateZ(45)的意思是绕z轴顺时针旋转45度。举例来说,如果物体中间线和z轴重合的话,绕z轴顺时针旋转45度就是指物体上半部分向左翻转,下半部分向右翻转;

Android中一共有两个Camera,分别为:

android.graphics.Camera android.hardware.Camera

今天我们要说的是第一个Camera,第二个主要应用在相机开发中。
首先看下这个类的官方介绍:

A camera instance can be used to compute 3D transformations and generate a matrix that can be applied, for instance, on a Canvas. 一个照相机实例可以被用于计算3D变换,生成一个可以被使用的Matrix矩阵,一个实例,用在画布上。

Camera内部机制实际上还是opengl,不过大大简化了使用。有了感性的认识之后,我们再来看下它的常用API定义:

Camera() 创建一个没有任何转换效果的新的Camera实例 applyToCanvas(Canvas canvas) 根据当前的变换计算出相应的矩阵,然后应用到制定的画布上 getLocationX() 获取Camera的x坐标 getLocationY() 获取Camera的y坐标 getLocationZ() 获取Camera的z坐标 getMatrix(Matrix matrix) 获取转换效果后的Matrix对象 restore() 恢复保存的状态 rotate(float x, float y, float z) 沿X、Y、Z坐标进行旋转 rotateX(float deg) rotateY(float deg) rotateZ(float deg) save() 保存状态 setLocation(float x, float y, float z) translate(float x, float y, float z)沿X、Y、Z轴进行平移

Matrix

Matrix是一个3 x 3的2D空间矩阵。Matrix,它是Android提供的一个矩阵工具类,是一个3x3的矩阵,一般要实现2D的旋转(绕z轴旋转)、缩放、平移、倾斜用这个作用于画布,这四种操作的内部实现过程都是通过matrix.setValues(…)来设置矩阵的值来达到变换的效果。

setTranslate(float dx,float dy)//:控制Matrix进行平移 setSkew(float kx,float ky,float px,float py)//:控制Matrix以px,py为轴心进行倾斜,kx,ky为X,Y方向上的倾斜距离 setRotate(float degress)//:控制Matrix进行旋转,degress控制旋转的角度 setRorate(float degress,float px,float py)//:设置以px,py为轴心进行旋转,degress控制旋转角度 setScale(float sx,float sy)//:设置Matrix进行缩放,sx,sy控制X,Y方向上的缩放比例 setScale(float sx,float sy,float px,float py)//:设置Matrix以px,py为轴心进行缩放,sx,sy控制X,Y方向上的缩放比例

API提供了set、post和pre三种操作,下面这个重点看下,之后效果会用到

post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。
pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。

结合使用:

Camera和Matrix的联合使用:
一般情况下,如果我们需要进行3D变换,那么需要将Camera和Matrix联合使用,
使用Camera进行x轴或y轴的旋转,
使用Matrix进行平移或放大。

canvas.concat(Matrix matrix)作用

canvas.concat的作用可以理解成对matrix的变换应用到canvas上的所有对象.

public class ConcatMatrixActivity extends Activity {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        getWindow().setFlags(                WindowManager.LayoutParams.FLAG_FULLSCREEN,                WindowManager.LayoutParams.FLAG_FULLSCREEN);        setContentView(new ConcatMatrixView(this));    }}public class ConcatMatrixView extends View {    private Matrix matrix = new Matrix();    private Paint bgPaint = new Paint();    public ConcatMatrixView(Context context) {        super(context);        matrix.setScale(2f, 2f);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        bgPaint.setColor(Color.RED);        canvas.drawRect(0, 0, 100, 100, bgPaint);        canvas.save();        canvas.concat(matrix);        canvas.drawRect(100, 100, 200, 200, bgPaint);        canvas.restore();        canvas.drawRect(400, 400, 500, 500, bgPaint);    }}

以上代码对matrix的x和y坐标都拉伸了2倍.变化的效果如下所示:

在没有concat的情况下canvas.drawRect(100, 100, 200, 200, bgPaint);是在(100, 100), (200, 200)的区域下画一个矩形.因为执行了matrix.setScale(2f, 2f)所以matrix的x和y坐标都拉伸了2倍.这时候在concat的作用下canvas.drawRect(100, 100, 200, 200, bgPaint)变成了在(200, 200), (400, 400)的区域上画矩形.
同理,如果把对matrix的变换由matrix.setScale(2f, 2f)改成matrix.setTranslate(100f, 100f),效果如下所示:

x轴和y轴坐标都移动了100个像素.

参考:android学习7——canvas.concat(Matrix matrix)作用

原创粉丝点击