在图形学中,数学是不可或缺的一部分,所以本书最开始的部分就是数学知识的复习。在图形学中,最常用的是矢量和矩阵,所以我根据前面三个章节的数学知识,总结一下数学知识。

一、矢量

  数学中的矢量,拥有方向和长度。其实矢量和点在坐标系中的表示完全一致(笛卡尔坐标系为准),区分矢量和点的关键,我觉得就是做平移。点是不能用平移操作来保证一致的,比如点A(1,2,3)经过平移矢量(1,2,3)后就是B(2,4,6),此时就是一个新的点。但是矢量经过相同平移操作后,还是矢量(1,2,3),这是因为矢量表示的是 vector head相对于 vector tail的偏移,平移操作并不会改变这种偏移。

  在矢量中一个关键就是坐标系,数学中的坐标系主要分为左手坐标系和右手坐标系。我时不时会弄混左手和右手坐标系,后来做了一个快捷的记忆:我的头是y方向,右手伸出来是x方向,那么如果z方向向前是正方向,那我就处于左手坐标系; 如果我的z方向向后是正方向,那我就处于右手坐标系。所以看起来我的脸决定了我的坐标系:)

矢量的数学操作主要是:加、减、乘三种操作,如果算上求模(求长度),那就是四种操作。A=(xa,ya,za), B=(xb,yb,zb)

加:A + B = (xa+xb, ya+yb, za+zb)

   减:A - B  = (xa-xb, ya-yb, za-zb)

  乘:A *B   = xaxb+yayb+zazb

模:||A||2= xa2 + ya2+za2

细心的会发现矢量乘的结果变成了一个数,确实,最终的结果就是一个数,其本质就是一种映射或者投影,表示的是A矢量在B矢量方向上的投影长度,矢量的乘可以用公式表示为:

  A *B   = ||A|| *||B|| * sinθ,其中θ为两个矢量的夹角(由于不熟悉博客的数学公式添加,只有先这写着了,后面熟练了再修改吧)

矢量中最常见的操作就是归一化,比如有一个矢量的序列{V0,v1,V2...},如何将这些矢量归一化为互相垂直的单位矢量?

这儿引入投影的一个表示:projn(V)= v . n/||n||, 表示的是v在n的单位矢量上的投影,那么对于矢量序列,我们可以这样进行正交归一化:

1)v0, v1,v2.......

2) w0 = v0;

3) w1 = v1 - projw0(v1)

4) w2 = v2 - projw0(v2) - projw1(v2)

........

根据上面的规律,可以得到正交化的规律:将当前矢量(第一个除外)去除在前面所有矢量上的分量(投影),得到的就是与前面各个适量正交的矢量。

最后我们将正交化的矢量进行归一化操作,即可得到一组正交归一化矢量序列。

矢量的最后一个知识点是:矢量的叉积,与矢量点积得到一个投影的结果值不同,矢量的叉积得到的是一个矢量,基本公式为:

AXB = (yazb -zayb, zaxb - xazb, xayb - yaxb),

   单看公式看不出规律,不过可以这样理解:xyz, yzx, zxy,分别去掉x, y , z,最后的结果就是三个分量的第一项,然后交换得到三个分量需要减去的第二项

矢量的叉积的实际意义,就是求得一个和A/B两个矢量都垂直的矢量,这在图形学中,可以用来求解游戏对象的一些常用矢量, 比如上(up)/下(down)/左(left)/右(right)/前(forward)/后(back)这些矢量都是互相垂直的,可以利用矢量的叉积得到。注意在笛卡尔坐标系中,矢量的叉积都是左手定律决定方向的,所以AXB和BXA是刚好方向相反的两个等长矢量。

二、矩阵

  在图形学中,我们会绘制各种各样的游戏实例,这些实例都是用基本的点(verts)和相关的贴图(textures)、材质(material)等共同设置渲染状态的。对于基本的顶点,常常需要做的一个基本操作就是变换:平移、旋转、缩放等。这些变换操作对应的就是矩阵的变换。

矩阵的定义就不再多说,就是一个nxm的同类元素的集合,通常这个元素就是数字(也可以为其他,这儿不再扩展)。

矩阵最基本的操作可以分为: 矩阵的乘, 矩阵的转置, 矩阵的行列式, 矩阵的逆

矩阵的乘积:  C = AB ≠BA

C矩阵中的每个元素是Cij是A矩阵的i行和B矩阵j列的对应点积的结果,基于此可以得到A矩阵的列数和B矩阵的行数是相等的(不然怎么做点积....)

矩阵的转置AT,就是将矩阵的行和列对换,说的简单点就是一列一列的变,新的每列是以前矩阵的每行竖着排列(感觉就是重新排队)

矩阵的行列式,是一个比较重要的点,Aij作为行列式的代指,就是去除A矩阵的i行和j列后得到的行列式计算结果,整体的公式为:

detA = ∑j=1n A1j(-1)i+jdetA1j

可以看出矩阵的行列式计算就是一个递归的计算过程,一般在图形学中的计算不会超过4x4的维度,所以可以用笔算的方式来计算这些矩阵的行列式:)

基于行列式,可以得到一个新的矩阵: 邻接矩阵A*,基于基本的矩阵A可以得到一个新的矩阵CA,其中的元素Cij = (-1)i+jdetAij,则可以定义邻接矩阵为:

A* = CAT  基于邻接矩阵,我们可以得到矩阵A的逆矩阵A-1 :A-1 = A*/detA

三、变换矩阵

基于矩阵的定义,我们可以将图形学中的一些常见的变换转化为对应的变换矩阵,这样在对点或者矢量进行变换的时候,其对应的数学操作就是一个变换矩阵的操作。基本的变换矩阵可以分为:缩放矩阵, 平移矩阵,旋转矩阵。

对于变换矩阵对矢量的作用,可以这样理解:u =(x,y,z) = xi + yj + zk, 那么一个变换操作可以表示为τ(u) = τ(xi + yj + zk) = xτ(i) + yτ(j) + zτ(k) = [x y z] [τ(i) τ(j) τ(k)]T = uA

所以说的直白点,就是用矩阵A来表示一种变换操作。那么具体如何表示呢?可以分拆为基本矩阵,然后进行合并即可。

1、缩放矩阵S

拆开用行向量表示为S(i) = (sx .1, sy.0, sz.0), S(j) = (sx .0, sy.1, sz.0),S(k) = (sx .0, sy.0, sz.1)

则缩放矩阵可以表示为S = [si , sj, sk]T, si = (sx,0,0), sj = (0,sy,0), sk = (0,0,sz)

2、旋转矩阵R

其实旋转矩阵是三个矩阵中相对比较难的矩阵,这儿给出一个旋转公式:

Rn(V) =  projn(v) + Rn(V⊥)

=  (n v) n + cosθ V⊥  + sinθ (n x v)

=  cosθ V + (1 - cosθ)(n v)n + sinθ(n x v)

具体的常用的三个旋转矩阵可以列出来:

3、平移矩阵T

平移矩阵比较简单,就不做推算,直接给出结果即可:

综合三种基本矩阵,我们可以进行组合得到一个较为复杂的变换矩阵。不过在图形学的计算中,对于三种矩阵的排序有一定的讲究,一般先用缩放矩阵S对当前的变换对象进行缩放,然后用旋转矩阵R进行旋转操作,最后用平移矩阵T进行平移操作,所以可以归并为SRT矩阵。

总结:经过基本的矢量,矩阵和变换的数学知识总结后,接下来就要进入正式的图形学知识了,我会在后面持续更新~

3D Game Programming withDX11 学习笔记(一) 数学知识总结的更多相关文章

  1. MyBatis:学习笔记(1)——基础知识

    MyBatis:学习笔记(1)--基础知识 引入MyBatis JDBC编程的问题及解决设想 ☐ 数据库连接使用时创建,不使用时就释放,频繁开启和关闭,造成数据库资源浪费,影响数据库性能. ☐ 使用数 ...

  2. C#学习笔记(基础知识回顾)之值类型与引用类型转换(装箱和拆箱)

    一:值类型和引用类型的含义参考前一篇文章 C#学习笔记(基础知识回顾)之值类型和引用类型 1.1,C#数据类型分为在栈上分配内存的值类型和在托管堆上分配内存的引用类型.如果int只不过是栈上的一个4字 ...

  3. C#学习笔记(基础知识回顾)之值传递和引用传递

    一:要了解值传递和引用传递,先要知道这两种类型含义,可以参考上一篇 C#学习笔记(基础知识回顾)之值类型和引用类型 二:给方法传递参数分为值传递和引用传递. 2.1在变量通过引用传递给方法时,被调用的 ...

  4. C#学习笔记(基础知识回顾)之值类型和引用类型

    一:C#把数据类型分为值类型和引用类型 1.1:从概念上来看,其区别是值类型直接存储值,而引用类型存储对值的引用. 1.2:这两种类型在内存的不同地方,值类型存储在堆栈中,而引用类型存储在托管对上.存 ...

  5. JAVA学习笔记—review基本知识[反射与异常]

    JAVA学习笔记—review基本知识[反射与异常] 1.异常: 1.1异常的分类: Java会将所有的异常封装成对象,其根本父类为Throwable. Throwable有两个子类:Error 和E ...

  6. Quartz学习笔记:基础知识

    Quartz学习笔记:基础知识 引入Quartz 关于任务调度 关于任务调度,Java.util.Timer是最简单的一种实现任务调度的方法,简单的使用如下: import java.util.Tim ...

  7. CUDA Programming Guide 学习笔记

    CUDA学习笔记 GPU架构 GPU围绕流式多处理器(SM)的可扩展阵列搭建,每个GPU有多个SM,每个SM支持数百个线程并发执行.目前Nvidia推出了6种GPU架构(按时间顺序,详见下图):Fer ...

  8. .net学习笔记---xml基础知识

    一.XML简介 XML是一种标记语言,用于描述数据,它提供一种标准化的方式来来表示文本数据.XML文档以.xml为后缀.需要彻底注意的是XML是区分大小写的. 先从一个简单的XML例子来了解下xml基 ...

  9. react学习笔记1--基础知识

    什么是react A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES[React是一个用于构建用户界面的JavaScript库.] React之所以快, ...

随机推荐

  1. html5知识点:DOM编程

    DOM是Document Object Model的缩写,中文名称是文档对象模型. DOM是处理HTML页面的标准编程接口,DOM可被JavaScript用来读取.改变HTML的内容和结构. 前端三大 ...

  2. Vim配置及使用笔记

    Vim配置及使用笔记 安装 apt-get install vim -y 配置说明 vim /etc/vim/vimrc 在配置文件后加入这些配置项 set nu set tabstop=4 set ...

  3. 写一个PHP函数,实现扫描并打印出指定目录下(含子目录)的所有jpg文件名

    写一个PHP函数,实现扫描并打印出指定目录下(含子目录)的所有jpg文件名 <?php $dir = "E:\照片\\";//打印文件夹中所有jpg文件 function p ...

  4. 多个Fragment的分开管理方案

    当项目里有多个Fragment的时候  我们希望让Fragment有个分类 并且展示的时候不会混淆在一起 例如:项目中导航栏有三个按钮   每个按钮对应一种分类的布局,每个分类的布局中有多个Fragm ...

  5. Python爬虫知识点四--scrapy框架

    一.scrapy结构数据 解释: 1.名词解析: o 引擎(Scrapy Engine)o 调度器(Scheduler)o 下载器(Downloader)o 蜘蛛(Spiders)o 项目管 ...

  6. udp和tcp

    tcp(Transmission Control Protocol 传输控制协议) 协议复杂,有序和可靠.编号和分段实现了有序,ACK(acknowledge)和重新发送实现了可靠. 滑窗实现了同时发 ...

  7. SQL基础知识一

    一.建库 show databases ;//显示已存在的数据库 create database 数据库库名; use 数据库名;//进入新建的数据 二.建表 show tables;//查询已存在的 ...

  8. javascript文档节点

    创建文本节点 document.createTextNode() 创建新文本节点,该方法接收一个参数,即要插入节点中的文本信息. <script> //创建一个div节点 var elem ...

  9. QQ空间掉帧率优化实战

    商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处. WeTest 导读 空间新业务需求日益增多,在业务开发阶段的疏忽,或者是受到其他业务的影响(比如一些非空间的业务网络回包或者逻辑在主线程 ...

  10. “核弹级”Android漏洞Janus,黑客可以任意篡改App

    美国时间12月9日,Google披露了一个名为"Janus"安卓漏洞.该漏洞可以让攻击者绕过安卓签名机制,从而让攻击者对App进行篡改,安卓5.0到8.0等个版本系统均受影响. 顶 ...