剑英陪你玩转图形学 (三) 归去来

发表于2015-09-20
评论0 1.5k浏览
今天的主题是数学,尤其是要把向量说一说


开篇废话
王全安又进去了,最近不太好引用岛国文化来开篇,来点民族的。
恰逢中秋,让我想起了一首脍炙人口的水调歌头。


明月几时有,把酒问群友。
不知这次版本,今晚能出否。
我欲推倒重构,又恐项目经理,深夜对我吼。
增删改代码,好像没保存…..

深呼吸,看屏幕,泪在流。
不应有恨,谁没忘记存代码?
人有悲欢离合,码有丢失冲突,此事古难全。
但愿人长久,leader别发现。



小伙伴们中秋都是怎么过的?有没有项目经理深吼你呢?

欢迎来德云社听相声,哦不,来听李总讲故事,好像也不对,我们是一个玩代码系列,图形学方向。


图形学是个综合学科,他的很大一部分都是3D数学。
图形学用的3D数学,客户端逻辑用的3D数学,有什么不一样的?
我不知道分界线在哪里,我只知道做游戏客户端,3D数学无处不在。
既然躲不开,就让我们来好好享受一番吧。
快速提高班
现在,教大家一些快速提高自己业务(zhuangbi)水平的方法。

今天讲提高业务水平的最后一个要诀,悟。

悟是你一定要钻研出一些你自己的观点。百度搜不到的东西。
这样和别人交流业务的时候,可以极大的提高别人对你的印象。

忍、持、悟。这次已经把全套秘籍都教给你了,让我们来回顾一下。
忍:不要主动去教别人,别人有疑惑会找你,主动去教容易招致反感。
持:要有选择的回答,拿不准的东西不要乱答,提升准确性。
悟:要有自己的观点。

学会这一套,业务(zhuangbi)水平就会一发不可收拾。


现在给大家简单的介绍一下unity3D的数学库,对提升业务水平有帮助哦。

基本数学工具:
UnityEngine.Mathf
集中了float型数值计算的相关数学函数的静态类型,比如cos sin sqlr
相对System.Math 更加实用,因为我们最长使用的数据类型是float,Mathf会更方便。
UnityEngine.Random
随机数产生器,和System.Random 使用方法不同,原理一样,只是静态化了,可以少写两行。
特定的数学工具:
特定的数学工具对应的数学函数就在这个类型内
Vector2 Vector3 Vector4
表示向量或者顶点,他们的相关计算函数都在Vector2 Vector3 Vector4内。
比如Vector3.Cross 叉积 Vector3.Dot 点积
Rect
表示一个2D矩形区域
Bounds
表示一个3D的方块区域
Matrix4X4
表示矩阵,矩阵用土的掉渣的方式表示一个空间变换,旋转跳跃我眯着眼。
Quaternion
表示四元数,四元数用土的掉渣的方式表示一个旋转,这个我们文后会介绍。
常用的数学工具就这些,当然还有float,这个我们最最常用的数学工具。

理解计算的意义
说到数学,对很多人来说是帮助睡眠小助手。
睡前两行数学书,包你一夜好睡眠。
确实对着那些名词,是会让人混混欲睡的。
现在开始上图片。

图片3.jpg (16.6 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传


上错图了,不好意思

图片4.png (26.74 KB, 下载次数: 1)

下载附件  保存到相册

2014-9-18 13:35 上传

阿基米德说:给我一个支点,我就能撬动地球

图片5.jpg (7.61 KB, 下载次数: 1)

下载附件  保存到相册

2014-9-18 13:35 上传

卡马克说:给我一个像素,我就能弄一个3D引擎

图片6.png (5.71 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传

李总说:……….



……….
伟人们告诉我们,要学真东西就得从零单排。
我准备了一组例子


下文所提的例子可以在线使用
http://lightszero.github.io/basemath/outweb.html
例子代码可以从这个页面直接下载哦。



随机数有什么用
随机对应固定,产生更多自然的变化。但是随机数也是受控的,这是概率论方面的问题了,
我们准备了两个例子,一个是用随机数来求圆周率

图片7.jpg (37.27 KB, 下载次数: 1)

下载附件  保存到相册

2014-9-18 13:35 上传


可以用随机数来求圆周率
随机在贴图上画点,把圆内和圆外的分别统计出来,可知圆的面积是0.5*0.5*PI,正方形的面积是1*1.
则PI = 圆的面积/方的面积*4.
画的总点数可以认为是方的面积
落在圆内的点数可以认为是圆的面积
另一个是用随机数来分布角色

图片8.png (65.93 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传


图中一屏幕的苍老师,是用随机数来分布的,你每次打开都会不一样。
向量
向量是本篇的重点

Vector3是一个数据结构,既可以表示标量点,也可以表示一个向量。
你希望他是什么他就是什么,这也是很多小伙伴困惑的地方。
这其实是我们在编程中只关心数值所产生的一个普遍问题。
想想float,单位和功能并不在其中。
表达缩放,float可以,表达速度,float 可以,表达长度,float可以,表达时间,float可以。
赋予数据结构何等意义,是人类该考虑的问题。

对于坐标的加减法,这些自不必提,我们来厘清一下点积和叉积这两个非常重要的运算。

向量点积的意义:

还记得盟军敢死队把敌军的视野标识出来诞生的玩法么?判断我们的猪脚是否暴露在敌人的圆锥形视野中,就要依靠点积。
点积的意义主要在于求出两个向量的夹角,试想一下,夹角和视野的关系。
在shader的光照模型中,用三角面的法线和光线方向确定光强,用向量求夹角,这就是点积的意义。

图片11.png (35.87 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传


关于点积我们准备了一个例子

图片12.png (65.93 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传


一屏幕的苍老师,鼠标的位置表示红音老师的目光方向。
红音老师的目光范围是左右30度。
红音老师目光所及的位置苍老师是白色的,看不到的位置苍老师是红色的。

向量叉积的意义:

如果你有一队飞机,在飞行过程中想让他们保持队形,向量叉积的计算就刚好可以满足你,叉积求出和两个向量垂直的向量。
利用这个特性可以随时计算出队长的前后左右上下正方向,当然也可以按别的什么东西对齐。
在直接绘图相关的计算中,叉积的一大应用是自动计算法线。与一个三角面的任意两边垂直的向量一定与这个三角面垂直,就是这个三角面的法线。

图片14.jpg (6.63 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传


关于叉积我们也准备了一个例子

图片15.png (50.16 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传

  

图片16.png (61.8 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传


无论红音老师看向哪个方向,红音军团总会保持阵型屹立在红音老师的周围

插插插
插值,可以说是客户端开发中最主要的思想。
是动画的基础思想,对Vector3来说,插值有着两种截然不同的意义。
因为Vector3同时表达两种意义,作为标量他表示3D空间中的一点。
对点和点的坐标插值,就是两点间的一条直线。

图片17.jpg (38.72 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传


延既定路线运动,基本都是对点的插值而来

作为向量Vector3表达一个方向,对方向和方向插值,就是一个旋转扇面。

图片18.jpg (54.05 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传


比如经典的小蛤蟆,他的脸是你指哪里就转向哪里
但是作为向量时直接使用Vector3插值,会得到奇异的结果。

图片19.jpg (34.6 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传


如图,从方向A插值到方向B,直接用Vector插值,会导致中间值的长度改变,在AB180度时,再想想这个奇异的结果。
对向量的插值,就要依靠四元数这个工具了,后文我们会顺便提一下。
向量的插值和顶点的插值,在直接绘图的计算中,有一个很典型的场合,骨骼动画。

图片20.png (49.4 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传



我们也准备了一个插值的例子
在上面的基础上改为红音老师鼠标点击后才转向。
会通过插值逐渐转向
但是红音军团为了快速完成保卫任务,采用直线移动,最后会保持阵型不变。
红音军团通过坐标插值移动。
本篇讲到这里就结束了,再会。后面捎带介绍一下其他的数学工具。
向量弄清楚了,都不是问题。
矩阵
记得么,我们曾介绍过,矩阵是一个土的掉渣的数学工具
矩阵的意义是一个空间变换:旋转、跳跃、我眯着眼。
矩阵可以描述任何一种空间变换。大约有旋转、平移、缩放这些信息。
虽然矩阵,也可以描述出梯形变换和平行四边形推倒的效果,并不常用。
一个3*4矩阵内部保存了旋转、平移、缩放的参数。
可以保存一个矩阵,描述一个物体在另一个空间中的位置。

图片21.jpg (12.33 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传


插插插
遗憾的是,矩阵并不适合于插值。
仅有平移可以直接插值。
矩阵和Vector一样,对于旋转直接数学插值会产生奇异结果。
对于缩放,矩阵也会产生一个不明显的错误。

图片22.jpg (29.33 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传


如果模型进行xy轴不均匀的缩放,那么同一个矩阵并不适合这个模型的法线,会导致法线和表面不再垂直。
这也是为什么光照模型中要使用逆转置矩阵的原因。
四元数
四元数也是一个土的掉渣的描述工具,他描述的信息叫做轴角对。
轴角对,就是一个旋转轴,加一个旋转角度。
设轴向量为n,旋转角度为t
四元数的值为:
x = n.x * sin(t / 2)  
y = n.y * sin(t / 2)  
z = n.z * sin(t / 2)  
w = cos(t / 2)

至于超复数那套解释,知道一下用于提升业务(zhuangbi)水平就行了。
其实四元数这么存,只是为了四元数乘法直接得到两个旋转连接后得到的新的轴角对。
四元数这样保存,可以让四元数乘法直接变成旋转连接工具。

图片23.jpg (7.02 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传


红色的q1表示一个旋转,绿色的q2表示一个旋转,他们的乘法结果就是蓝色的q3。
四元数表达的信息是一个旋转变换,可以直接存一个四元数作为物体的旋转量。


另外插入一点个人的意见,也许满是无知与偏见,听一下就行了:
四元数发明于1843年,图形学诞生于1963年,可是1985年四元数才被用于表达旋转并逐渐推广。
用于图形学中的四元数,最重要的价值就是轴角对的一种计算工具。
我对超复数、非零四元数乘法环共轭作用实现转动那套并不信服,就像是马后炮一样。
如早认识到非零四元数乘法环共轭作用实现转动,又怎么会花了二十几年才找到一个表达旋转的适合方法。
插插插
四元数对于旋转的描述就是旋转轴+角度,没有比他更适更针对旋转插值的了。
骨骼动画中对于骨骼旋转的插值计算,都是使用四元数插值的。
区域
区域就是包围盒
有两种常用的形式
Axis Aligned Bounding Box
oriented bounding box
AABB 轴对齐包围盒。
OBB 定向包围盒。
是为了简化碰撞和包围测试的一种方法。将一堆东西包在一个盒子里

图片24.png (18.39 KB, 下载次数: 0)

下载附件  保存到相册

2014-9-18 13:35 上传


我找到一张图,说明的很形象,把小人包起来,判断小人在不在一个区域,判断他的盒子就快的多。
OBB是小人在自己空间中的盒子,他不随小人的旋转跳跃而变化。
AABB是小人在世界空间中的盒子,小人旋转就要重新生成。
除了碰撞盒,还有其他常用的包围形式
2D的Rect
3D的OBB AABB 还有碰撞球,胶囊体等等。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引