Unity(三)三维数学和坐标系统

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的相对旋转量

猜你喜欢

转载自blog.csdn.net/m0_54119099/article/details/125937859
今日推荐