矩阵
矩阵就是一行和列组织起来的矩形数字块。
矩阵可以理解为是向量的数组。
 
矩阵的维度和记法
矩阵的维度是包含多少行多少列!例如1行2列的矩阵
记法:矩阵m中,对于第1行第2列的元素,我们记为m12
 
方阵
行数和列数相同的矩阵,我们叫做方阵。一般情况下,我们研究的就是2x2, 3x3, 4x4的方阵
 
对角线元素
方阵中,行号和列号相同的元素就是对角线元素,其他的都是非对角线元素。
 
单位矩阵
对角线元素都为1,非对角线元素都为0的矩阵
 
转置矩阵
对于矩阵M,M的转置矩阵MT,
MT就是把M的行变为列,把M的列变成行
 
向量和矩阵
行向量:一行几列的矩阵
列向量:几行一列的矩阵
 
矩阵的运算:
标量和矩阵的乘法:
M = m11 m12 * 2 = 2*m11 2*m12
        m21 m22          2*m21 2*m22
矩阵中的每一个元素都与这个标量相乘,最终结果还是一个矩阵。
 
矩阵与矩阵相乘:
矩阵和矩阵的乘法,并不是什么形式都可以,必须让左边矩阵的列和右边矩阵的行保持一致,否则不能相乘。
矩阵与矩阵相乘的结果:还是一个矩阵,该矩阵的行数是左边矩阵的行数,该矩阵的列数就是右边矩阵的列数。
矩阵与矩阵相乘,不满足乘法交换律。

 
对于结果矩阵中的Cij
Cij = 左边矩阵的第i行的每个元素与右边矩阵的第j列的每个元素相乘的和。

  -
-
- a b c d f
g h i j k k
k

1x- + -2x4, 1x7 + -2x1/
5x- + 0x4, 5x7 + 0x1/ 3x- + -1x0 + 4x3, 3x0 + -1x7 + 4x-, 3x3 + -1x- + 4x2, 2x2 + 3x5 +4x3, 2x3 + 3x7 +4x4, 2x1 + 3x2 +4x5
2x2 + 7x5 +10x3, 2x3 + 7x7 +10x4, 2x1 + 7x2 +10x5
向量和矩阵的乘法
行向量:放在矩阵的左侧进行乘运算,左乘矩阵
列向量:放在矩阵的右侧进行乘运算,右乘矩阵
对于同一个向量同一个矩阵,这个向量左乘矩阵的结果,与右乘矩阵的结果不一致!
 
矩阵的几何意义:
对于给定的向量a,矩阵M,有aM = b,,那么我们可以说M将a转换到了b,那么一个向量乘以一个矩阵相当于做了一次坐标变换。
 
描述一个物体变换时的规律。
其中包括:旋转,缩放,投影,镜像等。
线性变换:从几何上来理解:变换前是直线,变换后依旧是直线,变换前是几何原点,那么变换后依旧是几何原点。如3x3
仿射变换:线性变换 + 平移,如4x4
 
矩阵的行列式(只存在于方阵中)
行列式不是矩阵,是一个标量(就是数)f
方阵的行列式:|M| 或 detM
 
二阶方阵的行列式的计算:

三阶方阵的行列式的计算:


2x2x8+ 3x5x1 + 7x3x3
-2x5x3 - 3x3x8 - 7x2x1 2x5 - 3x4
代数余子式:
代数余子式是数,对于n阶方阵,代数余子式:n*n个
对于n阶方阵中的每个元素都有一个代数余子式。
Cij = 去掉了第i行第j列,剩下的矩阵的行列式 * -1的 i+j 次幂。

矩阵

C11 =(4x2 - 3x1 ) x (-)(+)
C12 =(3x2 - 5x1 ) x (-)(+)
C13 =(3x3 - 5x4 ) x (-)(+)
C21 =(4x2 - 3x5 ) x (-)(+)
C22 =(2x2 - 5x5 ) x (-)(+)
C23 =(2x3 - 5x4 ) x (-)(+)
C31 =(4x1 - 4x5 ) x (-)(+)
C32 =(2x1 - 3x5 ) x (-)(+)
C33 =(2x4 - 3x4 ) x (-)(+) - -
-
- - -
标准伴随矩阵
对于矩阵M,M的标准伴随矩阵记做adjM
adjM = 就是M矩阵的代数余子式组成矩阵的转置矩阵。
 
矩阵的逆:
方阵的M的逆,记做:M-1
对于矩阵来说,并不是所有的矩阵都有逆矩阵。
如果一个矩阵的行列式不为0,证明这个矩阵是由逆矩阵,可逆的。
如果一个矩阵的行列式为0,证明这个矩阵是不可逆的。
对于一个有逆矩阵的矩阵来说,我们叫做该矩阵是可逆的或非奇异的。
对于一个没有逆矩阵的矩阵来说,该矩阵是不可逆的或奇异的。
 
逆矩阵 = 标准伴随矩阵 / 矩阵的行列式
 
求逆矩阵:
1.求矩阵的行列式,判断矩阵是否可逆
2.求矩阵的标准伴随矩阵(代数余子式组成矩阵的转置矩阵)
3.求逆矩阵
矩阵

矩阵的行列式
|M| = - = - 标准伴随矩阵
-
- 转置矩阵
-
- 逆矩阵
-/ /
/ -/
矩阵

矩阵的行列式
|M| = ++ --- = - 标准伴随矩阵
-
-
- 转置矩阵
-
-
- 逆矩阵
-/ /
/ -/ -/
-/ -/ /
逆矩阵的几何意义:对于M矩阵实现的变换,M的逆矩阵表示的就是相反的变换。
 
旋转矩阵:

 
X' = (Cosθ,Sinθ)
Y' = (-Sinθ,Cosθ)
 
2D旋转变换的矩阵
组成矩阵
Cosθ  Sinθ
-Sinθ  Cosθ
 
如果旋转角为45度
0.707 0.707
-0.707 0.707 
 
对于坐标(1, 0)
0.707 0.707
-0.707 0.707 * (1, 0) = (0.707,0.707),代表绕着Z轴旋转45度的变换
 
3D旋转变换的矩阵
绕X轴旋转的矩阵(左乘):
1    0    0
0    Cosθ    Sinθ
0    -Sinθ    Cosθ
绕Y轴旋转的矩阵
Cosθ    0     -Sinθ
0          1     0
Sinθ     0     Cosθ   
绕Z轴旋转的矩阵
Cosθ    Sinθ    0
-Sinθ    Cosθ    0
0    0     1
 
(1, 2, 0),绕Z轴旋转30度
0.866  0.5  0
-0.5  0.866  0
0  0  1
 
x = 1x0.866 + 2x-5 + 0x0 = 
y = 1x0.5 + 2x0.866 + 0x0 =
z = 1x0 + 2x0 + 0x1 =
 
缩放矩阵:
对于给定的向量(X, Y),缩放X轴缩放Sx倍,Y轴缩放Sy倍
最终结果是(X*Sx, Y*Sy)
 
            m11 m12
(X, Y) * m21 m22
X1 = X*m11 + Y*m21
Y1 = X*m12 + Y*m22
X1 = X*Sx
Y1 = Y*Sy
X*Sx= X*m11 + Y*m21
Y*Sy= X*m12 + Y*m22
m11 = Sx  m12 = 0
m21 = 0    m22 = Sy
 
最终的2D的缩放矩阵
Sx  0
0   Sy
 
最终的3D的缩放矩阵
Sx  0  0
0  Sy  0
0  0  Sz 
Sx 对应的是X的值的缩放系数
Sy 对应的是Y的值的缩放系数
Sz 对应的是Z的值的缩放系数
缩放系数为1的时候,表示没有缩放
 
投影矩阵:
对于XY的投影矩阵(把Z的坐标变为0,其他两个不变)
1  0  0
0  1  0
0  0  0
 
对于XZ平面的投影矩阵
1  0  0
0  0  0
0  0  1
 
对于YZ平面的投影矩阵
0  0  0
0  1  0
0  0  1
 
镜像矩阵:
对于以YZ平面镜像的矩阵
-1  0  0
0  1  0
0  0  1
 
对于以XZ平面镜像的矩阵
1  0  0
0  -1  0
0  0  1
 
对于以XY平面镜像的矩阵
1  0  0
0  1  0
0  0  -1
 
平移:
对于给定向量(x, y, z)平移一个(x', y', z')的向量的位置
对于向量表示方向:(x, y, z)
对于向量表示坐标:(x+x', y+y', z+z')
                    m11  m12  m13
(x, y, z) *  m21  m22  m23
                    m31  m32  m33
X1 = X*m11 + Y*m21 + Z*m31 
Y1 = X*m12 + Y*m22 + Z*m32 
Z1 = X*m13 + Y*m23 + Z*m33
三维坐标不能表示平移
 
齐次坐标
(x, y, z)从三维的矢量变成四维(x, y, z, w)
当 w = 1 时,证明 x, y, z 表示的是点
当 w = 0 时,证明 x, y, z 表示的是方向
                    m11  m12  m13  m14
(x, y, z) *  m21  m22  m23  m24
                    m31  m32  m33  m34
                    m41  m42  m43  m44
 
X1 = X*m11 + Y*m21 + Z*m31 + W*m41
Y1 = X*m12 + Y*m22 + Z*m32 + W*m42 
Z1 = X*m13 + Y*m23 + Z*m33 + W*m43 
W1 = X*m14 + Y*m24 + Z*m34 + W*m44
 
X1 = X*m11 + Y*m21 + Z*m31 + W*m41 = x + x'
m11=1; m21=0; m31=0; m41=x';
 
Y1 = X*m12 + Y*m22 + Z*m32 + W*m42  = y + y'
m12=0; m22=1; m32=0; m42=y';
 
Z1 = X*m13 + Y*m23 + Z*m33 + W*m43  = z + z'
m13=0; m23=0; m33=1; m43=z';
 
W1 = X*m14 + Y*m24 + Z*m34 + W*m44 = w
m14=0; m24=0; m34=0; m44=1;
 
使用 4x4 的矩阵表示三维向量的平移(左乘矩阵)
1  0  0  0
0  1  0  0
0  0  1  0
x'  y'  z'  1
这是平移的左乘矩阵
 
使用 4x4 的矩阵表示三维向量的旋转
绕Z轴旋转
Cosθ  Sinθ  0  0
-Sinθ  Cosθ  0  0
0  0  1  0
0  0  0  1
 
复合变换:
Cosθ  Sinθ  0  0
-Sinθ  Cosθ  0  0
0  0  1  0
x'  y'  z'  1
 
对于(0, 0, 0)这个点,沿着x轴平移1个单位,再绕着z轴旋转90度
先平移再旋转的结果(0, 1, 0)
先旋转再平移的结果(1, 0, 0)
 
                       0  1  0  0
                      -1  0  0  0
                       0  0  1  0
(0, 0, 0, 1)  *   -1  0  0  1  =  (1, 0, 0, 1)
 
 
旋转 * 平移 = 复合变化(复合变换要注意顺序)
 Cosθ  Sinθ    0  0         1  0  0  0           Cosθ  Sinθ  0  0
-Sinθ  Cosθ   0  0         0  1  0  0         -Sinθ  Cosθ  0  0 
 0        0        1  0          0  0  1  0           0        0      1  0 
 0        0        0  1   *     x'  y'  z'  1   =    x'        y'     z'  1 
 
案例-动态生成网格

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CreateMesh : MonoBehaviour
{
void Start () { MeshFilter mf = gameObject.AddComponent<MeshFilter>();
MeshRenderer mr = gameObject.AddComponent<MeshRenderer>(); //先实例化一个网格
Mesh mesh = new Mesh(); //确定网格的四个顶点
//先创建一个Vector3类型的数组
Vector3[] vertexs = new Vector3[];
vertexs[] = new Vector3(-, , );
vertexs[] = new Vector3(, , );
vertexs[] = new Vector3(-, -, );
vertexs[] = new Vector3(, -, ); //把顶点给mesh
mesh.vertices = vertexs; //再确定顶点组成三角面的顺序,注意数组的数量一定是3的倍数
//因为3个顶点才能组成1个三角面,注意三角面的顶点的顺序,顺时针在正面,逆时针在反面
int[] triangles = new int[] {,,,,,};
mesh.triangles = triangles; //最终把网格给MeshFilter
mf.mesh = mesh;
}
}

using UnityEngine;
using System.Collections;
public class buildMesh : MonoBehaviour { public Vector3 vertLeftTopFront = new Vector3(-,,);
public Vector3 vertRightTopFront = new Vector3(,,);
public Vector3 vertRightTopBack = new Vector3(,,-);
public Vector3 vertLeftTopBack = new Vector3(-,,-);
private float waitN = 3f;
private float waitD = 3f;
public int shapeN = ; void Start ()
{
MeshFilter mf = GetComponent<MeshFilter>();
Mesh mesh = mf.mesh; //Vertices//
Vector3[] vertices = new Vector3[]
{
//front face//
vertLeftTopFront,//left top front, 0
vertRightTopFront,//right top front, 1
new Vector3(-,-,),//left bottom front, 2
new Vector3(,-,),//right bottom front, 3
//back face//
vertRightTopBack,//right top back, 4
vertLeftTopBack,//left top back, 5
new Vector3(,-,-),//right bottom back, 6
new Vector3(-,-,-),//left bottom back, 7
//left face//
vertLeftTopBack,//left top back, 8
vertLeftTopFront,//left top front, 9
new Vector3(-,-,-),//left bottom back, 10
new Vector3(-,-,),//left bottom front, 11
//right face//
vertRightTopFront,//right top front, 12
vertRightTopBack,//right top back, 13
new Vector3(,-,),//right bottom front, 14
new Vector3(,-,-),//right bottom back, 15
//top face//
vertLeftTopBack,//left top back, 16
vertRightTopBack,//right top back, 17
vertLeftTopFront,//left top front, 18
vertRightTopFront,//right top front, 19
//bottom face//
new Vector3(-,-,),//left bottom front, 20
new Vector3(,-,),//right bottom front, 21
new Vector3(-,-,-),//left bottom back, 22
new Vector3(,-,-)//right bottom back, 23
}; //Triangles// 3 points, clockwise determines which side is visible
int[] triangles = new int[]
{
//front face//
,,,//first triangle
,,,//second triangle
//back face//
,,,//first triangle
,,,//second triangle
//left face//
,,,//first triangle
,,,//second triangle
//right face//
,,,//first triangle
,,,//second triangle
//top face//
,,,//first triangle
,,,//second triangle
//bottom face//
,,,//first triangle
,,//second triangle
}; //UVs//
Vector2[] uvs = new Vector2[]
{
//front face// 0,0 is bottom left, 1,1 is top right//
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,),
new Vector2(,)
}; mesh.Clear ();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uvs;
;
mesh.RecalculateNormals(); } void Update ()
{
if(waitN > 0f)
{
waitN -= Time.deltaTime;
}
else
{
waitN = waitD;
shapeN ++;
if(shapeN > )
{
shapeN = ;
}
}
//morph to cube//
if(shapeN == )
{
vertLeftTopFront = Vector3.Lerp(vertLeftTopFront, new Vector3(-,,),Time.deltaTime);
vertRightTopFront = Vector3.Lerp(vertRightTopFront, new Vector3(,,),Time.deltaTime);
vertRightTopBack = Vector3.Lerp(vertRightTopBack, new Vector3(,,-),Time.deltaTime);
vertLeftTopBack = Vector3.Lerp(vertLeftTopBack, new Vector3(-,,-),Time.deltaTime);
}
//morph to pyramid//
if(shapeN == )
{
vertLeftTopFront = Vector3.Lerp(vertLeftTopFront, new Vector3(,,),Time.deltaTime);
vertRightTopFront = Vector3.Lerp(vertRightTopFront, new Vector3(,,),Time.deltaTime);
vertRightTopBack = Vector3.Lerp(vertRightTopBack, new Vector3(,,),Time.deltaTime);
vertLeftTopBack = Vector3.Lerp(vertLeftTopBack, new Vector3(,,),Time.deltaTime);
}
//morph to ramp//
if(shapeN == )
{
vertLeftTopFront = Vector3.Lerp(vertLeftTopFront, new Vector3(-,-,),Time.deltaTime);
vertRightTopFront = Vector3.Lerp(vertRightTopFront, new Vector3(,-,),Time.deltaTime);
vertRightTopBack = Vector3.Lerp(vertRightTopBack, new Vector3(,0.5f,-),Time.deltaTime);
vertLeftTopBack = Vector3.Lerp(vertLeftTopBack, new Vector3(-,0.5f,-),Time.deltaTime);
}
//morph to roof//
if(shapeN == )
{
vertLeftTopFront = Vector3.Lerp(vertLeftTopFront, new Vector3(-,0.2f,),Time.deltaTime);
vertRightTopFront = Vector3.Lerp(vertRightTopFront, new Vector3(,0.2f,),Time.deltaTime);
vertRightTopBack = Vector3.Lerp(vertRightTopBack, new Vector3(,0.2f,),Time.deltaTime);
vertLeftTopBack = Vector3.Lerp(vertLeftTopBack, new Vector3(-,0.2f,),Time.deltaTime);
}
Start();
}
}

Unity3D学习笔记(三十三):矩阵的更多相关文章

  1. Unity3D学习笔记(十三):委托、考试复习

    委托:比较什么时候用委托好   下课案例:不用下课铃 1.ClassManager需要拿到所有教室的引用,课堂管理者应该只负责计时并告知每间教室 2.每间教室应该是由当班老师负责是否需要下课,而课堂管 ...

  2. PHP学习笔记三十三【自定义错误处理器】

    <?php //自定义错误处理器 //$errorno 错误号 //$errmes错误信息 //这两个参数是必须的 function my_error($errorno,$errmes) { e ...

  3. 【Unity 3D】学习笔记三十三:游戏元素——天空盒子

    天空盒子 一般的3D游戏都会有着北京百年一遇的蓝天.让人惊叹不已.事实上天空这个效果没有什么神奇的仅仅需用到天空盒子这个组件即可.能够将天空设想成一个巨大的盒子,这个盒子将整个游戏视图和全部的游戏元素 ...

  4. Unity3D学习笔记3——Unity Shader的初步使用

    目录 1. 概述 2. 详论 2.1. 创建材质 2.2. 着色器 2.2.1. 名称 2.2.2. 属性 2.2.3. SubShader 2.2.3.1. 标签(Tags) 2.2.3.2. 渲染 ...

  5. VSTO 学习笔记(十三)谈谈VSTO项目的部署

    原文:VSTO 学习笔记(十三)谈谈VSTO项目的部署 一般客户计算机专业水平不高,但是有一些Office水平相当了得,尤其对Excel的操作非常熟练.因此如果能将产品的一些功能集成在Office中, ...

  6. Unity3D学习笔记2——绘制一个带纹理的面

    目录 1. 概述 2. 详论 2.1. 网格(Mesh) 2.1.1. 顶点 2.1.2. 顶点索引 2.2. 材质(Material) 2.2.1. 创建材质 2.2.2. 使用材质 2.3. 光照 ...

  7. Unity3D学习笔记6——GPU实例化(1)

    目录 1. 概述 2. 详论 3. 参考 1. 概述 在之前的文章中说到,一种材质对应一次绘制调用的指令.即使是这种情况,两个三维物体使用同一种材质,但它们使用的材质参数不一样,那么最终仍然会造成两次 ...

  8. Unity3D学习笔记7——GPU实例化(2)

    目录 1. 概述 2. 详论 2.1. 实现 2.2. 解析 3. 参考 1. 概述 在上一篇文章<Unity3D学习笔记6--GPU实例化(1)>详细介绍了Unity3d中GPU实例化的 ...

  9. Unity3D学习笔记8——GPU实例化(3)

    目录 1. 概述 2. 详论 2.1. 自动实例化 2.2. MaterialPropertyBlock 3. 参考 1. 概述 在前两篇文章<Unity3D学习笔记6--GPU实例化(1)&g ...

  10. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

随机推荐

  1. XMLHttpRequest对象(Ajax)的状态码(readystate) HTTP状态代码(status)

    2018-11-28 14:19:00 来自 :XMLHttpRequest对象(Ajax)的状态码(readystate)  HTTP状态代码(status) XMLHttpRequest对象(Aj ...

  2. MySql 存储过程 光标只循环一次

    [1]MqSql 存储过程 光标只循环一次 针对MySql存储过程,光标只循环一次就退出的场景,可能原因分析: (1)存储过程有问题(仔细检查语法.控制变量.条件等等) (2)保证存储过程正确.调用过 ...

  3. freedom is a kind of responsibility

    张维迎教授在2017年7月1日北大国发院2017届毕业典礼上的发言<自由是一种责任> 张维迎:自由是一种责任    本文为张维迎教授在2017年7月1日北大国发院2017届毕业典礼上的发言 ...

  4. Eclipse创建maven工程后没有build path解决方案

    1.修改maven工程下的.project文件为如下内容 <?xml version="1.0" encoding="UTF-8"?> <pr ...

  5. linux下安装mysql(rpm文件安装)

    数据库包下载: https://www.mysql.com/downloads/ 在GPL开原协议的社区开源版里边下载 我们用mysql community server里边的 其中workbench ...

  6. I2S接口介绍

    I2S接口介绍一.I2S协议介绍 I2S协议作为音频数据传输协议,由Philips制定.该协议由三条数据线组成:1.SCLK:串行时钟,频率= 2 * 采样频率 * 采样位数.2.WS:字段(声道)选 ...

  7. linux 二级域名设置

    首先,你的拥有一个有泛域名解析的顶级域名,例如: domain.com 其次,在 httpd.conf 中打开 mod_rewrite 之后,在 httpd.conf 的最后,添加以下内容: Rewr ...

  8. Porsche Piwis Tester II Diagnostic Tool -Next Generation of PIWIS Tester KTS520

    Porsche Piwis Tester II is the latest inspect equipment of Porsche Company. This is the latest profe ...

  9. 在vim编辑器python实现tab补全功能

    在vim编辑器中实现python tab补全插件有Pydiction,Pydiction可以实现下面python代码的自动补全: 1. 简单python关键词补全 2. python函数补全带括号 3 ...

  10. 大数据自学2-Hue集成环境中使用Sqoop组件从Sql Server导数据到Hive/HDFS

    安装完CDH后,发现里面的东东实在是太多了,对于一个初学大数据的来说就犹如刘姥姥进了大观园,很新奇,这些东东每个单拿出来都够喝一壶的. 接来来就是一步一步地学习了,先大致学习了每个模组大致做什么用的, ...