3D数学

匿名 (未验证) 提交于 2019-12-02 23:32:01

参考文章1:https://www.cnblogs.com/msxh/p/6156004.html

参考文章2:https://blog.csdn.net/qq_38186269/article/details/81396571

参考文章3:https://www.cnblogs.com/lixiang-share/p/5025662.html

1.向量

(1)向量是有大小和方向的有向线段。向量的大小就是向量的长度(模),向量有非负的长度。

(2)点和向量的关系:任意一点都能用从原点开始的向量来表达。

(3)零向量没有方向。

(4)向量点乘:分量乘积的和,是一个标量,[x,y,z].[a,b,c]=ax+by+cz。几何解释:点乘结果描述了两个向量的“相似”程度,点乘结果越大,两个向量越相近,θ = arccos(a・b)。

(5)向量叉乘:叉乘只能用来计算3D向量,它需要输入两个向量返回结果是另一个向量。得到的结果垂直于输入的两个向量。"左手坐标系"可以用来表示输入和输出的向量的方向。如果第一个参数匹配手的拇指和食指匹配第二个参数,结果将是中指的方向。如果参数的顺序是相反的结果向量将指向正好相反的方向,但将有相同长度。向量叉乘的结果的大小等于输入向量的乘积,然后通过它们之间的角度的正弦值乘以该值的大小。

  • 几何解释:叉乘得到的向量垂直于原来的两个向量。
  • ab|| = ||a|| ||b|| sin
  • ||ab||也等于以ab为两边的平时四边形的面积。
  • 叉乘最重要的应用就是创建垂直于平面、三角形、多边形的向量。

(6)点乘和叉乘的应用
点乘:两个向量点乘得到一个标量 ,数值等于两个向量长度相乘后再乘以二者夹角的余弦值 。如果两个向量a,b均 为单位 向量 ,那么a.b等于向量b在向量a方向上的投影的长度。

点乘后得到的是一个值:

若结果 = 0,则两向量互相垂直 。
若结果 < 0 ,则两向量夹角大于90°。
若结果 >0 ,则两向量夹角小于 90°。

叉乘:两个向量的叉乘得到一个新的向量 ,新向量垂直于原来的两个向量再乘夹角的正弦值。

叉乘后得到的还是一个向量:

在Unity3D里面。两个向量的点乘所得到的是两个向量的余弦值,也就是-1 到1之间,0表示垂直,-1表示相反,1表示相同方向。 两个向量的叉乘所得到的是两个向量所组成的面的垂直向量,分两个方向。 简单的说,点乘判断角度,叉乘判断方向。 形象的说当一个敌人在你身后的时候,叉乘可以判断你是往左转还是往右转更好的转向敌人,点乘得到你当前的面朝向的方向和你到敌人的方向的所成的角度大小。

(7)向量的点乘(Dot)判断角度,向量的叉乘(Cross)判断方向。

(8)点乘在Unity中的使用是用来计算两个物体之间角度,用Vector2.Dot()或Vector3.Dot()方法可以得到一个弧度制,也就是这两个物体夹角的弧度值,可以使用Mathf.Acos(弧度制)*Rad2Deg来转换为夹角的角度值。对于点乘的理解2D的理解起来比较简单,数学中的勾股定理,当知道斜边长度为a,一条直角边长度为b,夹角为R,那么b = a*cosR。

(9)叉乘判断方向,叉乘是两物体的法向量,举个例子,当我们的主角没有面对怪物时,我们可以先用点乘计算出当前主角的朝向和怪物当前朝向的角度,然后用叉乘我们可以判断出怪物是在我们的前?后?左?右?根据右手定则,当指向我们自己时,四指是逆时针,指向我们面朝方向时四指是顺时针,无论当前指向哪里,超过180度时都会变换朝向,所以叉乘时时刻刻都会告诉我们怎么转是最近的,Unity中我们用Vector3.Cross()计算两物体的叉乘,返回值是一个Vector3类型,最大为1最小为-1。

2.矩阵

(1)矩阵在3D引擎底层实现中使用的非常多,对于矩阵,我们从固定流水线开始理解,固定流水线是指一个3D物体在显示器上成像的过程,在这个过程中就用到了非常多的矩阵转换。用一个比较好理解的方式来说吧,首先,当我们需要一个3D模型时,会让美工开始在3DMax里面制作,制作完成导出FBX格式,当前这个模型就是一个个体,也就是局部坐标,然后我们会把模型导入Unity中调整位置,进行拖拽,这个过程使得模型从单个个体变为了Unity中模型的其中之一,也就是世界坐标,此时我们要看到该模型,所以添加摄像机,把模型放在摄像机视野内,这样,又从世界坐标变成了观察坐标,当然,摄像机看不到的模型背面就会被优化掉,那么观察坐标就变成了裁剪坐标,之后为了把模型显示在屏幕上,又把裁剪坐标变为视口坐标,最后进行光栅化完成固定流水线。

(2)物体的缩放,旋转,位移,虽然我们直接用Rotate等函数就可以很便捷的完成,但是其底层实现也是矩阵的变换,这里说一个小点,3D空间中,点是三维的,而矩阵是四维,这里涉及到了齐次坐标,进行矩阵计算时,会把三维的点转变成齐次坐标然后才可以计算,因为像位移,旋转,缩放等三维矩阵是完成不了的,点转为齐次坐标时会用1补齐第四位比如(x,y,z,1)。

(3)在3D数学中,矩阵往往代表一种变换,这也是坐标系转换所依赖的数学原理。

(4)Unity中的四种坐标系:模型坐标系、世界坐标系、摄像机坐标系、屏幕坐标系。

(5)“MVP”矩阵:是通过矩阵操作实现坐标系的转换的一种方式(也是3D图像显示的一个流程)。从模型本身坐标利用_ObjectToWorld(M矩阵)转换到世界坐标系;再利用_WorldToCamera(V矩阵)从世界坐标系转换到摄像机坐标系;最后利用_Projection(P矩阵)实现从摄像机到屏幕坐标系的转换,最终把3D图像显示在屏幕上。

(6)矩阵的行列式、转置、四则运算、逆矩阵等。

3.四元数

(1)四元数在Unity中主要用于做旋转使用,这里说几个很常用的四元数方法,Quaternion.Eular()可以获取物体的四元数,Rotation就是一个四元数,但是不可以直接对它进行赋值,这里可以用到eularAngle 进行赋值,控制物体的旋转可以用AngleAxis()方法进行操作。

4.欧拉角

使用欧拉角进行旋转赋值时一定可能性会出现万向节死锁,什么是万向节死锁,其实万向节死锁的原因是欧拉角本身,欧拉角旋转赋值一般情况下是一对一,比如,旋转X轴,旋转Y轴,旋转Z轴,但是在一些情况下会变成一对多,比如旋转Z轴,X轴和Z轴进行了旋转使得整体旋转发生改变,X轴的旋转自由缺失,这种情况最好的避免方式是,仅对一个轴进行赋值,其余轴为0。直接使用欧拉角的代码效率还是比较高的。

文章来源: https://blog.csdn.net/q123_xi/article/details/88790287
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!