Unity-3D数学基础
Mathf
Mathf和Math
Math是C#自带的工具类,在包含在system中
Mathf是unity封装的类,包含math中的方法,多了一些适用于游戏开发的方法
一般情况下,我们在游戏开发中使用mathf进行数学计算
Mathf中的常用方法
圆周率:
1 | print(Mathf.PI); |
取绝对值
1 | print(Mathf.Abs(-10)); |
向上取整
1 | print(Mathf.CeilToInt(1.01f)); |
向下取整
1 | print(Mathf.FloorToInt(1.6f)); |
钳制函数
1 | int a = Random.Range(5, 30); |
获取最大(小)值
1 | print(Mathf.Max(1,2,3,4,5,6)); |
一个数的n次幂
1 | print(Mathf.Pow(4, 2)); |
一个数的平方根
1 | Print(Mathf.Sqrt(4)); |
四舍五入
1 | print(Mathf.RoundToInt(4.2f)); |
判断一个数是否是2的n次方
1 | print(Mathf.IsPowerOfTwo(4)); |
判断正负
1 | print(Mathf.Sign(-10)); |
插值运算
1 | float result = Mathf.Lerp(start, end, t); |
也就是result = start + (end - start) * t;
用法一
1 | private float start; |
接近速度先快后慢,位置无限接近
用法二
1 | private float time; |
匀速变化,t>=1时得到结果
三角函数
弧度、角度相互转化
令,rad = 1;则anger = rad*57.29578……
弧度转角度
1 | float rad = 1; |
角度转弧度
1 | float anger = 1; |
三角函数
1 | print(Mathf.Sin(30*Mathf.Deg2Rad)); |
坐标系
世界坐标系
transform.position/rotation/eulerAngles的变化会影响一个物体的世界坐标
物体坐标系
物体的右方为x轴,前方为z轴,上方为y轴
transform.localPosition/LocalRotation/localScale的变化会影响一个物体的局部坐标
屏幕坐标系
原点:屏幕左下方
向右为x轴正方向,向上为y轴正方向
视口坐标系
类似屏幕坐标系,左下角为(0,0),右上角为(1,1)
坐标转换
世界转本地
transform.InverseTransformDirection等方法
本地转世界
transform.TransformDirection等方法
世界转屏幕
camera.main.WorldToScreenPoint
屏幕转世界
camera.main.ScreenToWorldPoint
世界转视口
Camera.main.WorldToViewportPoint
视口转屏幕
Camera.main.ViewportToScreenPoint
向量
默认你已经有向量的数学基础
点积
用点积判断物体位置
1 | private Vector3 _target; |
用点积求得角度
1 | [private Transform _target; ] |
虽然我们可以直接用Vector3.Angle获得角度
叉乘
叉乘的几何意义
详见线性代数的本质 | 紫地丁的个人博客 (purpleditine.top)
叉乘计算
1 | Debug.Log(Vector3.Cross(transform.forward,target.position-transform.position)); |
向量插值运算
线性插值
1 | Vector3.Lerp(start,end,t); |
球形插值
1 | Vector3.Slerp(start,end,t); |
四元数!!!
为何要使用四元数
欧拉角旋转约定
heading-pitch-bank
也就是先绕y再x再z旋转
unity中的欧拉角
transform.eulerAngles得到的就是欧拉角
欧拉角的优缺点
优点:直观易理解,储存空间小,可以从一个方向到另一个方向旋转超过180度
缺点:同一旋转的表示不唯一,万向节死锁
无伤理解欧拉角中的“万向死锁”现象_哔哩哔哩_bilibili
四元数是什么
概念
四元数由实数和三个虚数组成,用于在三维空间中表示旋转
构成
一个四元数包含一个标量和一个3D向量
[w,v],w为标量,v为3D向量
任意一个四元数表示一个三维空间中的旋转
轴-角对
在3D空间中,任意旋转都可以表示绕着某个轴旋转一个旋转角得到
对于给定旋转,假设为绕着n轴,旋转b度,n轴为(x,y,z)
那个可以构成四元数
Q = [cos(b/2),sin(B/2)n] ,或
Q = [cos(b/2),sin(B/2)x,sin(B/2)y,sin(B/2)z]
Unity中的四元数
初始化
1 | Quaternion q = new Quaternion(Mathf.Sin(30*Mathf.Deg2Rad),0,0,Mathf.Cos(30*Mathf.Deg2Rad)); |
四元数和欧拉角相互转化
欧拉角转四元数
Quaternion.Euler(x,y,z)
四元数转欧拉角
Quaternion q;
q.eulerAngles
四元数常用方法
单位四元数
单位四元数没有旋转量(角位移)
Quaternion.identity
插值运算
在四元数中Lerp和Slerp差别不大,由于算法不同,Slerp的效果会好一些,慢一些
1 | A.rotation = Quaternion.Slerp(A.rotation, B.rotation, t); |
向量指向转四元数
1 | Quaternion q = Quaternion.LookRotation(B.position - A.position); |
四元数计算
四元数相乘
两个四元数相乘得到一个新的四元数,代表两个旋转量的叠加,旋转相对的是局部坐标
四元数乘向量
四元数乘向量返回一个原向量旋转后的新向量