Unity(三)三维数学和坐标系统
因为Unity 3D中有关Vector3的三维数学内容相对难以理解且重要,所以想再理解体会一下。
向量
Vector3:一种数据类型,表示3D的向量和点。包含位置、方向、欧拉角的信息,也包含做些普通向量运算的函数。
要获取世界坐标原点到位置坐标的向量可以使用物体的Position属性
Vector V=transform.position
position.magnitude
方法可以获得此向量的模,position.normalized
方法可以获得与此向量同向的单位向量。
Direction=A.position-B.position
可以获取两个物体的向量差,向量指向被减数。
值得一提的是,移动方法Translate()
的参数就可以给予一个向量,对应物体就会沿着该向量方向移动大小等同于该向量模大小的距离、
坐标系统
Unity中主要有四种坐标系:
1.全局坐标系: 即世界坐标系,整个场景的固定坐标,在游戏场景中表示每个物体的固定位置和方向;
**2.局部坐标系:**即物体坐标系,每个物体独立的坐标系,原点为模型轴心点,随着物体的旋转或者移动而改变,表现物体间的相对位置和方向;
**3.屏幕坐标系:**把屏幕看作一个坐标系,屏幕左下角是(0,0),右上角为屏幕的最大宽高。Z轴的坐标是相机的世界坐标中Z轴坐标的负值;
**4.视口坐标系:**视口坐标系跟屏幕坐标系相似,只不过将Game视图的屏幕坐标系单位化,左下角依旧是(0,0)。右上角变为(1,1),比较适合用比例来计算。
各个坐标系也有相对应的转换方法:
从局部坐标系到全局坐标系可以用transform.TransformPoint()
方法
例:Vector WorldPoint=transform.TransformPoint(Vector3 E)
参数E为物体自身局部坐标系的对应位置,该方法将会返回物体自身坐标系对应E位置的点在全局坐标系中的位置
从全局坐标系到局部坐标系可以用transform.InverseTransformPoint()
方法
从屏幕坐标系到全局坐标系可以用Camera.main.ScreenToWorldPoint()
方法
从全局坐标系到屏幕坐标系可以用Camera.main.WorldToScreenPoint()
方法
从视口坐标系到全局坐标系可以用Camera.main.ViewportToWorldPoint()
方法
从全局坐标系到视口坐标系可以用Camera.main.WorldToViewportPoint()
方法
欧拉角
欧拉角的思想是将物体绕某一轴的一次旋转,分解为依次分别绕X、Y、Z轴的三次旋转。这三个轴分别旋转的转动角度,就是一组三个欧拉角,X与Z轴以自身坐标系为准旋转,Y轴则以全局坐标系旋转。
欧拉角的数据类型也是Vector3数据类型,但是它没有方向没有大小的概念,他的x
-y
-z
表示的是各个轴向上的旋转角度。而position有方向,有大小,他的x
-y
-z
表示的是各个轴向 上的有向位移。
万向节死锁
欧拉角的一大缺点便是会产生万向节死锁问题,它是由欧拉旋转定义本身造成的。
如图,当欧拉角先绕X轴旋转±90度的时候,这时物体自身的Z轴和全局坐标系的Y轴重合了,若物体此时再沿着Z轴或Y轴旋转,会发现失去了一个旋转自由度,这就是万向节死锁问题。
欧拉角只用三个数字表达方位,且符合人的思考方式,但是它会产生万向节死锁问题,
这时候我们就需要引入四元数的相关概念。
四元数
四元数不会产生万向节死锁并且能够很容易被插值,它用于表示旋转,Unity使用Quaternion表示所有旋转,它由一个三维向量(X-Y-Z)
和一个标量W
组成,旋转轴为Vector3
,旋转弧度为θ
,其中
x=sin(θ/2)*Vector3.x
y=sin(θ/2)*Vector3.y
z=sin(θ/2)*Vector3.z
w=cos(θ/2)
它们的取值范围都为-1~1
tranform组件的变量rotation,它的类型就是四元数
Quaternion qt=transform.rotation
相关API
Vector3
一些静态变量:
back | 即Vector3(0, 0, -1); |
---|---|
down | 即Vector3(0, -1, 0); |
forward | 即Vector3(0, 0, 1); |
left | 即Vector3(-1, 0, 0); |
one | 即Vector3(1, 1, 1); |
right | 即Vector3(1, 0, 0); |
up | 即Vector3(0, 1, 0); |
zero | 即Vector3(0, 0, 0); |
magniude | 返回向量的长度 |
SqrMagnitude | 返回向量的长度平方 |
1.float angle = Angle(Vector a, Vector b)
:返回a向量和b向量之间的夹角
2.Vector3 b = Vector3.ClampMagnitude(a, float length)
:返回一个和a向量同方向的b向量,模长为length
3.Vector3 c = Vector3.Cross(Vector a, Vector b)
:返回a与b的叉乘
4.float distance = Vector3.Distance(Vector a, Vector b
:返回a与b坐标之间的直线距离
5.float c = Vector3.Dot(Vector a, Vector b)
:返回a与b之间的点乘结果
6.Vector3 c = Vector3.Lerp(Vector a, Vector b, float t)
:返回两个点之间的线性插值
7.Vector3 force = Vector3.Project(Vector3 a, Vector3 b)
:返回值为a在b上的投影向量
8.Vector3 force = Vector3.ProjectOnPlane(Vector3 a, Vector b)
:返回值为a在b对应过世界原点平面的投影
9.Vector3 result = Vector3.Reflect(Vector3 a, Vector3 b)
:返回值为a以b为法线反射出去的反射光线向量
Quaternion
1.Quaternion.Euler(Vector3 angle)
:以欧拉角构建四元数,使该四元数变化以该欧拉角旋转,该旋转以世界坐标为准旋转,返回该旋转
transform.rotation
方法等价于Quaternion.Euler(Vector3 Angle)
方法
2.Quaternion.AngleAxis(float angle, Vector3 axis)
:该四元数变化绕着axis轴向旋转angle角度,返回该旋转
3.Quaternion.Angle(Quaternion a, Quaternion b)
:获得a和b两个四元数之间的角度
4.Quaternion.FromToRotation(Vector3 a, Vector3 b)
:返回从a旋转到b的相对旋转量
Quaternion.Angle(Quaternion a, Quaternion b)
:获得a和b两个四元数之间的角度
4.Quaternion.FromToRotation(Vector3 a, Vector3 b)
:返回从a旋转到b的相对旋转量