Unity --- Vector3的使用,欧拉角与四元数

1.Vector3是啥?

 representation of .... (表示...) --- 相对应的vector2就是2d的

Vector3是UnityEngine类下的一个静态结构体,这个结构体中有许多成员方法以及三个最重要的成员变量 : x ,y ,z 均为单精度浮点型float

创建vector3类型的变量的时候有三种初始化方式,一种是什么都不加,如下图

 一种是加两个参数 x ,y,还有种是加三个参数x,y,z

2.通过vector3类型创建的变量可以表示为一个向量,也可以表示为一个坐标(点),还可以表示为一个旋转(表示旋转的时候括号内的参数是旋转角),还还可以表示缩放(x,y,z)三个方向上的缩放

3.在c#中创建一个浮点数的时候,默认为双精度浮点数,如果是想创建一个单精度浮点数的话,我们要在这个浮点数后面加上一个 f ,比如 : 0.5f

4.Vector3结构体中提供了很多静态的属性来帮助我们给vector3变量初始化:比如

vector.zero(把这个赋值给变量,可以直接把变量的参数初始化为(0,0,0))

vector.one ---- (1 , 1, 1 )

 还有back,right,left,up,down等等,到时候可以自己去看看

5.也可以直接通过结构体变量名+ 点操作符 + 成员参数民来访问和操作成员参数

6.通过结构体名调用Vector结构体中的静态方法angle --- 传两个vector变量作为参数 ,方法的返回值是将这两个作为向量时的向量夹角。

如果是调用distance方法的话,传的两个参数会被当作坐标(点),返回值是两个点之间的距离

用Dot方法的话,就是当向量求点乘,返回点乘后的值

如果是Cross方法的话,当向量求叉乘,返回叉乘后得到的新Vector变量

调用Lerp方法的话,要传三个参数,插值中的t参数的范围是0到1,通过这个方法我们可以获得一个沿着固定起点向固定终点不断移动的向量/点/刻度/旋转

 7.直接通过变量调用magnitude(向量模长)属性,可以获得当前向量的模长

调用normalized属性我们可以获得将变量规范化后(单位长度化)的新变量


欧拉角 --- 与旋转有关 

 这个面板中的Rotation中的每一个参数都是欧拉角,范围是0到360°

通过欧拉角控制物体旋转并不是有三个旋转角度参数就足够了,我们还需要一个参数来表示x,y,z三个旋转角度的旋转顺序

原因是通过欧拉角体系来描述旋转时,不同的旋转顺序带来的旋转结果是不一样的

人们认为归定了这个顺序参数是X - Y - Z

然后欧拉角旋转时一个很重要的特点是:

顺序在前的轴转动时会带动顺序在后的轴转动,这是因为欧拉角的旋转原理是相对于改变前的自身坐标系进行旋转的,但是顺序在后的轴转动时顺序在前的轴不会跟着转动

欧拉角的转动其实就是新的自身坐标系(整体)相对于旧的自身坐标系顺/逆时针转动一定的角度(欧拉角:0~360°),比如下面这个:

第一次欧拉角旋转:新的自身坐标系Y轴顺时针相对于旧的自身坐标系Y轴转动(一个轴的转动会带动整个坐标系转动,因为相互垂直的关系要保持)

 第二次欧拉角转动:原本是新的坐标系的Y轴转化为旧的坐标系Y轴,然后在转动的时候生成一个新的坐标系Y轴顺时针相对于旧坐标系Y轴旋转一个欧拉角

( 上面这个描述的是动态定义下的欧拉角,还有一种静态定义下的欧拉角,即相对于世界坐标系转动,但此处我们只讨论动态定义下的欧拉角)

继续回到欧拉角的特征上:即顺序在前的轴转动时会带着顺序在后的轴一起转动,但是顺序在后的轴转动时不会带动顺序在前的轴转动

根据这个特征我们就能够知道万向死锁出现的原因了:

如果我们先转Y轴(X轴和Z轴相互垂直),转动90°,根据上面的特性我们可以得知:X轴不会跟着转动,Z轴会跟着转动90°,此时就会出现一个现象:

Z轴和X轴重合了!!!,此时我们无论是绕X轴转还是绕Z轴转,得到的旋转结构都是一样的

由于发生了重合,三个旋转轴变成了两个,我们的物体丢失了一个旋转角度,或者说丢失了一个自由度

但是,这种论述只是方便解释的假设情况,真正的事实是:无论那个轴发生旋转都会带动另外两个轴发生旋转,那么在这种现实情况下又为什么会发生万向死锁呢?

变换和运动是不相同的!!

从A变为B,我们称为变换,这是两个状态的转变,是没有过程的,上一秒在起点下一秒在终点,这就是变换

而运动是有过程的,是连续的。在现实中,运动是由无数个变换组成的,从A到B的运动过程中我们执行了无数个变换,将这无数个变换的空间积分就成了宏观的距离,无数个时间积分就成了宏观的时间

电脑中的动画就是在模拟现实中的变换来实现运动。在电脑中所有的动画都可以在一定时间里拆分为有限数量的图片,这些图片都在一定的时间间隔内播放(这个时间间隔被称为帧)

上一帧的图片A变为下一帧的图片B,这就是一种变换而不是运动!!!当这些变换在一定时间内积累的足够多的时候就形成了运动(即连续)的假象

而欧拉角描述的就是变换而不是运动!

一个欧拉角变换过程是由三个分变换按照X-Y-Z的顺序组成的一个总变换,这三个分变换分别是:X轴变换,Y轴变换和Z轴变换,这三个变换组成一个总的变换后,得到一个结果姿态,然后我们会将初始姿态直接变为结果姿态

每一次的欧拉角变换都是在给定变换参数和顺序的情况下,将初始姿态变为结果姿态

而每一次的欧拉角变换的初始姿态都是固定的,即参数为0,0,0的情况


 四元数 --- 欧拉角进化版

在系统中表示旋转的一般不是欧拉角而是四元数

四元数是一个四维空间的高阶复数,它的效率很高,而且不会造成万向节死锁问题

WoW,看了半天,哎,先记个四元数旋转计算公式吧:

具体的公式可以自己上网找找 


Unity引擎带给我们的便利

在unity中,提供给了我们一个方法,当我们向这个方法传一个欧拉角的时候,它会放回一个对应的四元数给我们

Quaternion --- 四元数

创建一个四元数对象的方式有很多种,和Vector对象很类似

1.直接用new创建 - new Quaternion(传四个参数,分别是四元数的实部和三个虚部)

2.直接通过类/结构体名来调用四元数类/结构体中的静态属性来直接赋值创建:

identity : 通过这个赋值得到的四元数坐标如下

 3.通过方法转换将一个欧拉角转换为四元数,然后用这个四元数来赋值

方法是Quaternion中的静态方法Euler(欧拉)括号里面可以传三个角度参数,也可以直接传一个欧拉角进去。这个方法的返回值就是通过传进来的欧拉角转换而成的四元数 

4.

 调用这个LookRotation方法可以获得一个四元数

在括号里我们可以只传一个参数也可以传两个参数,当我们只传一个参数forward(向前)向量的时候,我们可以生成一个用来进行旋转的四元数,将这个四元数用于旋转的时候可以让物体的z轴与forward向量重合

也就是说forward向量影响的是Z轴的指向,而另一个upward向量影响的是Z轴的旋转

当我们只传一个upward向量的时候,就会返回一个用于旋转物体的y轴使得其与我们指定的upward向量平行/重合(对齐)的四元数

如果传两个参数的话,返回的就是一个能让物体Z轴和forward向量对齐的同时,让物体的y轴与upward向量对齐的四元数

注意上面进行旋转的都是物体的本地坐标系

LookRotation详解


5.通过四元数转为欧拉角

rotate是一个欧拉角,quaternion是一个四元数变量名,直接通过这个变量名调用Quaternion中euleAngles静态方法后,会将调用这个方法的四元数转换为对应的欧拉角,并将这个欧拉角返回。

猜你喜欢

转载自blog.csdn.net/qq_51947882/article/details/126455602