Files
AndroidNote/CustomView/Advance/[9]Matrix_Basic.md

318 lines
6.8 KiB
Markdown
Raw Normal View History

2016-07-23 01:18:44 +08:00
# Matrix基础篇
2016-06-06 17:39:12 +08:00
2016-07-20 06:10:39 +08:00
2016-07-26 06:08:56 +08:00
## 目录
2016-07-23 01:31:39 +08:00
2016-07-26 06:13:17 +08:00
- [Matrix简介](#jianjie)
2016-07-26 06:39:13 +08:00
- [概述](#gaishu)
2016-07-26 06:14:29 +08:00
- [常见误解](#wujie)
- [Matrix详解](#xiangjie)
2016-07-20 17:05:00 +08:00
2016-07-23 01:15:22 +08:00
******
2016-07-26 06:13:17 +08:00
<p id="jianjie" />
2016-07-26 06:08:56 +08:00
## Matrix简介
2016-07-23 01:15:22 +08:00
2016-07-26 06:39:13 +08:00
<p id="gaishu" />
2016-07-26 06:08:13 +08:00
**Matrix是一个矩阵主要功能是坐标映射数值转换。**
2016-07-26 06:02:36 +08:00
它看起来大概是下面这样:
2016-07-22 04:01:04 +08:00
![](http://latex.codecogs.com/png.latex?
$$
\\left [
\\begin{matrix}
MSCALE\\_X & MSKEW\\_X & MTRANS\\_X \\\\
\\\\
MSKEW\\_Y & MSCALE\\_Y & MTRANS\\_Y \\\\
\\\\
MPERSP\\_0 & MPERSP\\_1 & MPERSP\\_2
\\end{1}
\\right ]
$$)
2016-06-10 02:41:55 +08:00
2016-07-26 06:02:36 +08:00
下面我们看一下2D画布中常用的四种操作(translate, scale, rotate, skew)都是由哪些参数控制的。
2016-07-20 04:04:36 +08:00
2016-07-20 16:48:25 +08:00
![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f60gwrhlnyj30c008zdgy.jpg)
2016-07-22 23:21:08 +08:00
![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f633hvklfnj30c008zdge.jpg)
2016-07-20 04:04:36 +08:00
2016-07-26 06:18:07 +08:00
**从上图可以看到最后三个参数是控制透视的这三个参数主要在3D效果中运用通常为(0, 0, 1),不在本篇讨论范围内,暂不过多叙述,会在之后对文章中详述其作用。**
2016-07-20 04:04:36 +08:00
2016-07-26 06:14:29 +08:00
<p id="wujie" />
2016-07-22 04:01:04 +08:00
### 常见误解
2016-07-21 04:09:29 +08:00
2016-07-21 04:14:15 +08:00
**1.认为Matrix最下面的一行的三个参数(MPERSP_0、MPERSP_1、MPERSP_2)没有什么太大的作用,在这里只是为了凑数。**
2016-07-21 04:09:29 +08:00
2016-07-26 06:18:07 +08:00
实际上最后一行参数在3D变换中有着至关重要的作用这一点会在后面中Camera一文中详细介绍。
2016-07-21 04:09:29 +08:00
2016-07-21 17:15:35 +08:00
**2.最后一个参数MPERSP_2被解释为scale**
2016-07-21 04:09:29 +08:00
2016-07-26 06:18:07 +08:00
的确更改MPERSP_2的值能够达到类似缩放的效果但这是因为齐次坐标的缘故并非这个参数的实际功能。
2016-07-21 04:09:29 +08:00
2016-07-26 06:14:29 +08:00
******
2016-07-21 04:09:29 +08:00
2016-07-26 06:14:29 +08:00
<p id="xiangjie" />
2016-07-26 06:10:26 +08:00
## Matrix详解
2016-07-22 07:26:20 +08:00
2016-07-26 06:18:07 +08:00
Matrix 是一个矩阵,最根本的作用就是坐标转换,下面我们就看看几种常见变换的原理:
2016-07-24 02:53:41 +08:00
2016-07-26 06:02:36 +08:00
常见的基本变换有4种: 平移(translate)、缩放(scale)、旋转(rotate) 和 错切(skew)。
2016-07-24 03:17:36 +08:00
2016-07-26 06:02:36 +08:00
由于我们以下大部分的计算都是基于矩阵乘法规则,如果你已经把线性代数还给了老师,请参考一下这里:
2016-07-24 03:17:36 +08:00
**[维基百科-矩阵乘法](https://zh.wikipedia.org/wiki/%E7%9F%A9%E9%99%A3%E4%B9%98%E6%B3%95)**
2016-07-24 02:57:06 +08:00
2016-07-26 17:56:35 +08:00
### 1.缩放
2016-07-24 02:33:08 +08:00
2016-07-29 23:20:33 +08:00
![](http://latex.codecogs.com/png.latex?$$ x = k_1 x_0 $$)
![](http://latex.codecogs.com/png.latex?$$ y = k_2 y_0 $$)
2016-07-27 04:44:59 +08:00
用矩阵表示:
2016-07-24 03:06:46 +08:00
2016-07-24 03:17:36 +08:00
![](http://latex.codecogs.com/png.latex?
$$
\\left [
\\begin{matrix}
2016-07-27 04:44:59 +08:00
x\\\\
y\\\\
1
2016-07-24 03:17:36 +08:00
\\end{1}
\\right ]
=
\\left [
\\begin{matrix}
2016-07-29 23:20:33 +08:00
k_1 & 0 & 0 \\\\
0 & k_2 & 0 \\\\
0 & 0 & 1
2016-07-24 03:17:36 +08:00
\\end{1}
\\right ]
\\left [
\\begin{matrix}
2016-07-27 04:44:59 +08:00
x_0 \\\\
y_0 \\\\
1
2016-07-24 03:17:36 +08:00
\\end{1}
\\right ]
$$)
2016-07-27 05:31:57 +08:00
>
你可能注意到了我们坐标多了一个1这是使用了齐次坐标系的缘故在数学中我们的点和向量都是这样表示的(x, y),两者看起来一样,计算机无法区分,为此让计算机也可以区分它们,增加了一个标志位,增加之后看起来是这样: <br/>
>
(x, y, 1) - 点<br/>
(x, y, 0) - 向量<br/>
>
另外,齐次坐标具有等比的性质,(2,3,1)、(4,6,2)...(2N,3N,N)表示的均是(2,3)这一个点。(**将MPERSP_2解释为scale这一误解就源于此**)。
2016-07-31 03:49:17 +08:00
图例:
2016-07-31 05:44:38 +08:00
![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f6cnk02zy9j308c0dwwej.jpg)
2016-07-31 03:49:17 +08:00
2016-07-26 17:56:35 +08:00
### 2.错切
2016-07-24 15:58:35 +08:00
2016-07-31 03:21:14 +08:00
错切存在两种特殊错切,水平错切(平行X轴)和垂直错切(平行Y轴)。
#### 水平错切
2016-07-31 05:47:58 +08:00
![](http://latex.codecogs.com/png.latex?$$ x = x_0 + ky_0 $$)
2016-07-31 03:21:14 +08:00
![](http://latex.codecogs.com/png.latex?$$ y = y_0 $$)
用矩阵表示:
2016-07-26 04:36:27 +08:00
2016-07-26 04:20:03 +08:00
![](http://latex.codecogs.com/png.latex?
$$
\\left [
\\begin{matrix}
2016-07-27 19:50:35 +08:00
x\\\\
y\\\\
1
2016-07-26 04:20:03 +08:00
\\end{1}
\\right ]
=
\\left [
2016-07-27 19:50:35 +08:00
\\begin{matrix}
2016-07-31 03:21:14 +08:00
1 & k & 0 \\\\
0 & 1 & 0 \\\\
2016-07-29 23:57:36 +08:00
0 & 0 & 1
2016-07-26 04:20:03 +08:00
\\end{1}
\\right ]
\\left [
\\begin{matrix}
2016-07-27 19:50:35 +08:00
x_0\\\\
y_0\\\\
1
2016-07-26 04:20:03 +08:00
\\end{1}
\\right ]
$$)
2016-07-31 05:44:38 +08:00
图例:
![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f6cniifb0sj308c0dw3yz.jpg)
2016-07-31 05:47:58 +08:00
#### 垂直错切
![](http://latex.codecogs.com/png.latex?$$ x = x_0 $$)
![](http://latex.codecogs.com/png.latex?$$ y = kx_0 + y_0 $$)
用矩阵表示:
![](http://latex.codecogs.com/png.latex?
$$
\\left [
\\begin{matrix}
x\\\\
y\\\\
1
\\end{1}
\\right ]
=
\\left [
\\begin{matrix}
1 & 0 & 0 \\\\
k & 1 & 0 \\\\
0 & 0 & 1
\\end{1}
\\right ]
\\left [
\\begin{matrix}
x_0\\\\
y_0\\\\
1
\\end{1}
\\right ]
$$)
图例:
![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f6cnkwyksij308c0dwq3f.jpg)
2016-07-26 17:56:35 +08:00
### 3.旋转
2016-07-26 04:37:19 +08:00
2016-07-31 06:57:02 +08:00
假定一个点 A(x<sub>0</sub>, y<sub>0</sub>) ,距离原点距离为 r, 与水平轴夹角为 α 度, 绕原点旋转 θ 度, 旋转后为点 B(x, y) 如下:
![](http://latex.codecogs.com/png.latex? $$ x_0 = r \\cdot cos \\alpha $$)
![](http://latex.codecogs.com/png.latex? $$ y_0 = r \\cdot sin \\alpha $$)
2016-07-31 07:08:37 +08:00
![](http://latex.codecogs.com/png.latex?
$$
x = r \\cdot cos( \\alpha + \\theta)
= r \\cdot cos \\alpha \\cdot cos \\theta - r \\cdot sin \\alpha \\cdot sin \\theta
= x_0 \\cdot cos \\theta - y_0 \\cdot sin \\theta
$$)
![](http://latex.codecogs.com/png.latex?
$$
y = r \\cdot sin( \\alpha + \\theta)
= r \\cdot sin \\alpha \\cdot cos \\theta + r \\cdot cos \\alpha \\cdot sin \\theta
= y_0 \\cdot cos \\theta + x_0 \\cdot sin \\theta
$$)
2016-07-31 07:10:41 +08:00
用矩阵表示:
2016-07-26 05:13:51 +08:00
![](http://latex.codecogs.com/png.latex?
$$
\\left [
\\begin{matrix}
2016-07-29 01:39:19 +08:00
x\\\\
2016-07-31 06:03:12 +08:00
y\\\\
2016-07-28 04:48:35 +08:00
1
2016-07-26 05:13:51 +08:00
\\end{1}
\\right ]
=
\\left [
\\begin{matrix}
2016-07-31 07:10:41 +08:00
cos(\\theta) & -sin(\\theta) & 0 \\\\
sin(\\theta) & cos(\\theta) & 0 \\\\
0 & 0 & 1
2016-07-26 05:13:51 +08:00
\\end{1}
\\right ]
.
\\left [
\\begin{matrix}
2016-07-28 04:48:35 +08:00
x_0\\\\
y_0\\\\
1
2016-07-26 05:13:51 +08:00
\\end{1}
\\right ]
$$)
2016-07-31 07:10:41 +08:00
图例:
![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f6cpp174twj308c0dwt8s.jpg)
2016-07-26 05:13:51 +08:00
2016-07-26 17:56:35 +08:00
### 4.平移
2016-07-26 04:37:19 +08:00
2016-07-29 22:50:40 +08:00
![](http://latex.codecogs.com/png.latex?$$ x = x_0 + \\Delta x $$)
![](http://latex.codecogs.com/png.latex?$$ y = y_0 + \\Delta y $$)
2016-07-29 01:39:19 +08:00
![](http://latex.codecogs.com/png.latex?
$$
\\left [
\\begin{matrix}
x\\\\
2016-07-29 22:50:40 +08:00
y\\\\
2016-07-29 01:39:19 +08:00
1
\\end{1}
\\right ]
=
\\left [
\\begin{matrix}
2016-07-29 22:50:40 +08:00
1 & 0 & \\Delta x \\\\
0 & 1 & \\Delta y \\\\
2016-07-29 01:39:19 +08:00
0 & 0 & 1
\\end{1}
\\right ]
.
\\left [
\\begin{matrix}
x_0\\\\
y_0\\\\
1
\\end{1}
\\right ]
$$)
2016-07-22 02:47:02 +08:00
2016-07-21 04:09:29 +08:00
2016-07-20 17:05:00 +08:00
2016-07-20 04:04:36 +08:00
2016-07-20 01:45:13 +08:00
2016-07-26 06:02:36 +08:00
**Matrix方法表**
2016-07-21 03:09:37 +08:00
方法类别 | 相关API | 摘要
-----------|---------------------------------------------------------|------------------------
基本方法 | equals hashCode toString toShortString | 比较、 获取哈希值、 转换为字符串
2016-07-23 00:58:04 +08:00
数值操作 | set reset setValues getValues | 设置、 重置、 设置数值、 获取数值
数值计算 | mapPoints mapRadius mapRect mapVectors | 计算变换后的数值
2016-07-21 03:09:37 +08:00
设置(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 | 求逆矩阵、 是否为仿射矩阵、 是否为单位矩阵 ...
2016-06-13 17:01:01 +08:00
2016-06-11 21:46:30 +08:00