Matrix是什么
Matrix是一个矩阵,用于坐标映射,数制转换
- 可以运用于View、图片、动画效果等各个方面
- 画布操作是对Matrix的封装;Matrix更接近底层
基本原理
最根本的作用就是坐标转换
(这涉及到了图形学的知识)
我们所用到的变换均属于仿射变换,仿射变换是 线性变换(缩放,旋转,错切) 和 平移变换(平移) 的复合;
- **基本变换有4种: **平移(translate)、缩放(scale)、旋转(rotate) 和 错切(skew)
最后一行三个参数通常为0 0 1;(齐次矩阵)
- 各种转换,以及组合变换的前乘后乘等属于图形学的知识;因为写学习资料的博主写的很详细了……就懒得再记笔记了……(此处应有传送门:http://www.gcssloop.com/customview/Matrix_Basic)
Matrix方法表
基本方法 equals hashCode toString toShortString 比较、 获取哈希值、 转换为字符串
数值操作 set reset setValues getValues 设置、 重置、 设置数值、 获取数值
数值计算 mapPoints mapRadius mapRect mapVectors 计算变换后的数值
设置(set) setConcat setRotate setScale setSkew setTranslate 设置变换
前乘(pre) preConcat preRotate preScale preSkew preTranslate 前乘变换
后乘(post) postConcat postRotate postScale postSkew postTranslate 后乘变换
特殊方法 setPolyToPoly setRectToRect rectStaysRect setSinCos 一些特殊操作
矩阵相关 invert isAffine isIdentity 求逆矩阵、 是否为仿射矩阵、 是否为单位矩阵
Matrix方法详解
构造函数
1 | Matrix () |
方法
基本方法
1.equals
2.hashCode
3.toString //将Matrix转换为字符串: Matrix{[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]}
4.toShortString //将Matrix转换为短字符串: [1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]
数值操作
1.void set(Matrix src) // 若数值为空则同reset
2.void reset()
3.void setValues(float[] values)//setValues的参数是浮点型的一维数组,长度需要大于9,拷贝数组中的前9位数值赋值给当前Matrix。
4.void getValues(float[] values)
数值计算
- 1.mapPoints
1 | void mapPoints (float[] pts)//pts数组作为参数传递原始数值,计算结果仍存放在pts中 |
计算一组点基于当前Matrix变换后的位置
- 2.mapRadius
1 | float mapRadius(float radius) |
测量半径;由于圆可能因为画布变成椭圆;故此处测量的是平均半径;
- 3.mapRect
1 | boolean mapRect (RectF rect)//测量rect并将测量结果放入rect中,返回值是判断矩形经过变换后是否仍为矩形 |
测量矩阵变换后的位置
- 4.mapVectors
1 | void mapVectors (float[] vecs) |
mapVectors 与 mapPoints 基本上是相同的
mapVectors不会受到位移的影响
set、pre 与 post
对于四种基本变换 平移(translate)、缩放(scale)、旋转(rotate)、 错切(skew) 它们每一种都三种操作方法,分别为 设置(set)、 前乘(pre) 和 后乘 (post)
- 一开始从Canvas中获取到到Matrix并不是初始矩阵,而是经过偏移后到矩阵,且偏移距离就是距离屏幕左上角的位置
- 构造Matrix时使用的是矩阵乘法,前乘(pre)与后乘(post)结果差别很大
- 受矩阵乘法影响,后面的执行的操作可能会影响到之前的操作
特殊方法
- 1.setPolyToPoly
1 | boolean setPolyToPoly ( |
自由变换中的扭曲
setPolyToPoly最多可以支持4个点,这四个点通常为图形的四个角,可以通过这四个角将视图从矩形变换成其他形状
- 2.setRectToRect
1 | boolean setRectToRect (RectF src, // 源区域 |
将源矩形的内容填充到目标矩形中,然而在大多数的情况下,源矩形和目标矩形的长宽比是不一致的,这个填充的模式就由第三个参数 stf 来确定
ScaleToFit 是一个枚举类型,共包含了四种模式
CENTER 居中,对src等比例缩放,将其居中放置在dst中。
START 顶部,对src等比例缩放,将其放置在dst的左上角。
END 底部,对src等比例缩放,将其放置在dst的右下角。
FILL 充满,拉伸src的宽和高,使其完全填充满dst。
-
3.rectStaysRect
判断矩形经过变换后是否仍为矩形,假如Matrix进行了平移、缩放则画布仅仅是位置和大小改变,矩形变换后仍然为矩形,但Matrix进行了非90度倍数的旋转或者错切,则矩形变换后就不再是矩形了 -
4.setSinCos
设置sinCos值,这个是控制Matrix旋转的
1 | // 方法一 |
矩阵相关
- 1.invert
求矩阵的逆矩阵
1 | boolean invert (Matrix inverse) |
-
2.isAffine
判断矩阵是否是仿射矩阵 -
3.isIdentity
判断是否为单位矩阵
Matrix的技巧
1.获取View在屏幕上的绝对位置
1 |
|
Matrix Camera
因为之前学习过图形学的知识,还有unity3d;于是Camera理解起来就很轻松;Camera相当于用户在3D世界中的一个视角,好比用户的眼睛;
我们的手机屏幕是一个2D的平面,所以也没办法直接显示3D的信息,因此我们看到的所有3D效果都是3D在2D平面的投影而已
Camera主要作用就是这个,将3D信息转换为2D平面上的投影,实际上这个类更像是一个操作Matrix的工具类,使用Camera和Matrix可以在不使用OpenGL的情况下制作出简单的3D效果
Camera常用方法
基本方法 save、restore 保存、 回滚
常用方法 getMatrix、applyToCanvas 获取Matrix、应用到画布
平移 translate 位移
旋转 rotat (API 12)、rotateX、rotateY、rotateZ 各种旋转
相机位置 setLocation (API 12)、getLocationX (API 16)、getLocationY (API 16)、getLocationZ (API 16) 设置与获取相机位置
Camera则主要作用于3D空间
原文中有一部分是关于3D的知识;**
-
1.Camera使用的3D坐标系是左手坐标系;和2D坐标系的不同就是:2D坐标系的Y轴向下,而3D坐标系的Y轴向上;此外3D坐标系的Z轴垂直于屏幕向里
-
2.三维投影,通常为正交投影和透视投影;属于图形学的知识
正交投影就是我们数学上学过的 “正视图、正视图、侧视图、俯视图” 这些东西。
透视投影则更像拍照片,符合近大远小的关系,有立体感,我们此处使用的就是透视投影。
- 3.摄像机;Android 上面观察View的摄像机默认位置在屏幕左上角,而且是距屏幕有一段距离的
摄像机的位置默认是 (0, 0, -576)。其中 -576= -8 x 72
当距离为 -10 的时候,实际距离为 -720 像素
方法详解
基本方法
1 | camera.save(); // 保存状态 |
常用方法
- 1.getMatrix
1 | void getMatrix(Matrix matrix) |
计算当前状态下矩阵对应的状态,计算后赋值给matrix
- 2.applyToCanvas
1 | void applyToCanvas(Canvas canvas) |
计算当前状态下矩阵对应的状态,计算后赋值给canvas
平移
-
1.void translate (float x, float y, float z)
和2D平移类似,只不过是多出来了一个维度,从只能在2D平面上平移到在3D空间内平移 -
2.沿X轴平移
1 | camera.translate(x,0,0); |
- 3.沿Y轴平移
1 | Camera camera = new Camera(); |
1 | camera.translate(0, -y, 0); |
- 4.沿Z轴平移
**当View和摄像机在同一条直线上时: **此时沿z轴平移相当于缩放的效果,缩放中心为摄像机所在(x, y)坐标,当View接近摄像机时,看起来会变大,远离摄像机时,看起来会变小,近大远小
**当View和摄像机不在同一条直线上时: **当View远离摄像机的时候,View在缩小的同时也在不断接近摄像机在屏幕投影位置(通常情况下为Z轴,在平面上表现为接近坐标原点)。相反,当View接近摄像机的时候,View在放大的同时会远离摄像机在屏幕投影位置
旋转
旋转是Camera制作3D效果的核心,不过它制作出来的并不能算是真正的3D,而是伪3D,因为View是没有厚度的。
1 | void rotate (float x, float y, float z); |
旋转中心
旋转中心默认是坐标原点,对于图片来说就是左上角位置
在3D中没办法指定操作中心
//可以曲线救国;比如强行将旋转中心移动到Camera位置相同的地方
1 | Matrix temp = new Matrix(); // 临时Matrix变量 |
相机位置
使用translate和rotate来控制拍摄对象,也可以移动相机自身的位置
1 | void setLocation (float x, float y, float z); // (API 12) 设置相机位置,默认位置是(0, 0, -8) |
相机和View的z轴距离不能为0
虚拟相机前后均可以拍摄
摄像机右移等于View左移
出处:http://www.gcssloop.com/customview/Matrix_Basic