目录
1 三维空间里的旋转与欧拉角,四元数
1.1 欧拉角比较符合直观
1.2 四元数
1.3 下面是欧拉角和四元数的一些参考文章
2 关于旋转的这些知识点
2.1 使用euler欧拉角旋转
2.2 使用quaternion四元数,w,x,y,z
2.3 使用quaternion四元数,类 Vector3.zero 这种固定坐标了,固定的旋转?
2.4 利用unity编辑器,在unity里通过看向一个物体而实现旋转
2.5 互转
2.5.1 使用Euler转化为quaternion四元数
2.5.2 使用quaternion四元数转化为Euler角
3 逐一测试旋转效果
3.1 直接使用Euler角Vector3(0,30,0)来旋转
3.2 直接使用quaternion四元数旋转
3.3 将quaternion四元数转化为Euler角后旋转
3.4 用欧拉角转成四元数后旋转
3.5 直接用Quaternion.AngleAxis *Quaternion.AngleAxis 实现同时绕着多轴旋转
3.6 直接用Quaternion.AngleAxis *Quaternion.AngleAxis 实现同时绕着多轴旋转
3.7 下面是完整的测试草稿代码
4 未解决的问题
4.1 不了解为啥上面有的时候可以持续旋转,有时候只能旋转1次
4.2 关于下面的匀速代码
5 另外一种匀速代码
1 三维空间里的旋转与欧拉角,四元数
- 欧拉角,四元数,都是用来表达三维空间里的旋转的
1.1 欧拉角比较符合直观
欧拉角与四元数-CSDN博客文章浏览阅读1.6w次,点赞29次,收藏127次。一、欧拉角静态的定义对于在三维空间里的一个参考系,任何坐标系的取向,都可以用三个欧拉角来表现。参考系又称为实验室参考系,是静止不动的。而坐标系则固定于刚体,随着刚体的旋转而旋转。如图所示。设定xyz-轴为参考系的参考轴。称xy-平面与XY-平面的相交为交点线,用英文字母(N)代表。zxz顺规的欧拉角可以静态地这样定义:α\alphaα 是 x-轴与交点线的夹角,β\betaβ 是z-..._欧拉角和四元数的区别https://blog.csdn.net/ViatorSun/article/details/102713679
unity里的E,旋转,很明显表示方式就是欧拉角的3种旋转轴
1.2 四元数
- 我们用复数(两个数字)可以表示二维上的旋转,那么是不是用三个数字(三元数)可以表示三维空间中的旋转呢?数学家告诉我们不是的,要表示三维空间中的旋转,我们得用四元数。
- unity 里不只支持欧拉角,也支持用 四元数,表达三维空间里的旋转
-
四元数的基本数学方程为 : q = cos (a/2) + i(x * sin(a/2)) + j(y * sin(a/2)) + k(z * sin(a/2)) 其中a表示旋转角度,(x,y,z)表示旋转轴。
-
四元数的定义:q = [w,x,y,z]其中w是实部,当然也有资料会把四元数写成q = [x,y,z,w]其中w是实部。这都是正确的
-
注意:四元数q,有q^2 = 1.
若想要某个物体(i,j,k)绕着a(x,y,z)轴旋转θ度。
这个旋转用四元数表示就是q = ((x,y,z)sinθ/2, cosθ/2)
该物体用四元数表示为p = ((j,j,k),0)。
那么旋转之后的物体的点为p′,
则:
通过某个公式能算出p′的值。
Quaternion.AngleAxis (30.0f, transform.right) 这个方法的意思是创建一个四元数表示饶transform.right轴旋转30度。
四元数可以用*操作符来进行多个旋转操作比如:
transform.rotation =
Quaternion.AngleAxis (30.0f, transform.right) * Quaternion.AngleAxis (30.0f,transform.up);
也可以用 Quaternion.Euler 欧拉旋转表示四元数旋转比如:
transform.rotation = Quaternion.Euler (new Vector3 (0.0f, 30.0f, 20.0f)) * Quaternion.AngleAxis (30.0f, transform.forward);
如果想对一个向量做旋转做法如下:
Vector3 someVector = new Vector3 (1.0f,1.0f,1.0f);
Vector3 newVector = Quaternion.AngleAxis(90, Vector3.up) * someVector;Quaternion.LookRotation(某个向量v) 使得物体的朝向和v一致
利用四元数做差值(Quaternion.Slerp)旋转:
transform.rotation = Quaternion.Slerp (transform.rotation,Quaternion.Euler (new Vector3 (0.0f, 30.0f, 0.0f)) * Quaternion.AngleAxis (30.0f, transform.forward),Time.deltaTime * 0.33f);
1.3 下面是欧拉角和四元数的一些参考文章
https://zhuanlan.zhihu.com/p/267359507https://zhuanlan.zhihu.com/p/267359507
https://zhuanlan.zhihu.com/p/513687673https://zhuanlan.zhihu.com/p/513687673
https://www.zhihu.com/question/23005815https://www.zhihu.com/question/23005815
https://zhuanlan.zhihu.com/p/27471300https://zhuanlan.zhihu.com/p/27471300
2 关于旋转的这些知识点
2.1 使用euler欧拉角旋转
- Vector3 rotate1 = new Vector3(0,30,0);
- 在unity里表示,绕着Y轴旋转30度
2.2 使用quaternion四元数,w,x,y,z
- 其中W是实数部分
- xyz是虚数部分
- Quaternion quaternion1 = new Quaternion(0,0,0,0);
Quaternion.AngleAxis (30.0f, transform.right)
2.3 使用quaternion四元数,类 Vector3.zero 这种固定坐标了,固定的旋转?
- Quaternion quaternion2 = Quaternion.identity;
2.4 利用unity编辑器,在unity里通过看向一个物体而实现旋转
- quaternion2 = Quaternion.LookRotation(new Vector3(0,0,0));
2.5 互转
2.5.1 使用Euler转化为quaternion四元数
- quaternion2 = Quaternion.Euler(rotate1);
2.5.2 使用quaternion四元数转化为Euler角
- rotate2 = quaternion2.eulerAngles;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class rotateTest1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
//使用euler欧拉角旋转
Vector3 rotate1 = new Vector3(0,30,0);
//使用quaternion四元数,xyzw?
Quaternion quaternion1 = new Quaternion(0,0,0,0);
//使用quaternion四元数,类 Vector3.zero 这种固定坐标了,固定的旋转?
Quaternion quaternion2 = Quaternion.identity;
//利用unity编辑器,在unity里通过看向一个物体而实现旋转
//重新给quaternion2赋值
quaternion2 = Quaternion.LookRotation(new Vector3(0,0,0));
///互转
//使用Euler转化为quaternion四元数
quaternion2 = Quaternion.Euler(rotate1);
//使用quaternion四元数转化为Euler角
//给rotate2赋值,需要先定义rotate2
Vector3 rotate2 = new Vector3(0,0,0);
rotate2 = quaternion2.eulerAngles;
}
// Update is called once per frame
void Update()
{
}
}
3 逐一测试旋转效果
3.1 直接使用Euler角Vector3(0,30,0)来旋转
Vector3 rotate1 = new Vector3(0,30,0);
this.transform.Rotate(rotate1);
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class rotateTest1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//使用euler欧拉角旋转
Vector3 rotate1 = new Vector3(0,30,0);
this.transform.Rotate(rotate1);
}
}
3.2 直接使用quaternion四元数旋转
- w,xyz ,其中w是实数部分,xyz都是*i的虚数部分
- 比如
- new Quaternion(0.866f,0,0,0.5f);
- new Quaternion(0,0,0,0);
- Quaternion.identity;
- //quaternion1不能持续旋转这个方法?this.transform.Rotate(quaternion1);
- //只能用this.transform.rotation 旋转到指定位置,而不能持续旋转
- this.transform.rotation = quaternion1;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class rotateTest1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//使用euler欧拉角旋转
//Vector3 rotate1 = new Vector3(0,30,0);
//使用quaternion四元数,w,xyz ,其中w是实数部分,xyz都是*i的虚数部分
Quaternion quaternion1 = new Quaternion(0.866f,0,0,0.5f);
//quaternion1不能持续旋转这个方法?this.transform.Rotate(quaternion1);
//只能用this.transform.rotation 旋转到指定位置,而不能持续旋转
this.transform.rotation = quaternion1;
}
}
3.3 将quaternion四元数转化为Euler角后旋转
- quaternion1.eulerAngles 可以将quaternion四元数转化为Euler角
- rotate2 = quaternion1.eulerAngles;
Quaternion quaternion1 = new Quaternion(0.866f,0,0,0.5f);
Vector3 rotate2 = new Vector3(0,0,0);
rotate2 = quaternion1.eulerAngles;
this.transform.Rotate(rotate2);
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class rotateTest1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
Quaternion quaternion1 = new Quaternion(0.866f,0,0,0.5f);
Vector3 rotate2 = new Vector3(0,0,0);
rotate2 = quaternion1.eulerAngles;
this.transform.Rotate(rotate2);
}
}
3.4 用欧拉角转成四元数后旋转
// 创建一个表示xx度旋转欧拉角,然后转换为的四元数,表示绕Y轴旋转
Quaternion rotate3 = Quaternion.Euler(0, 45, 0);
// 假设你有一个现有的四元数
Quaternion originalQuaternion = Quaternion.identity;
// 转换为30度旋转
Quaternion newQuaternion = rotate3 * originalQuaternion;
// 应用到游戏对象
this.transform.rotation = newQuaternion;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class rotateTest1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
// 创建一个表示xx度旋转欧拉角,然后转换为的四元数,表示绕Y轴旋转
Quaternion rotate3 = Quaternion.Euler(0, 45, 0);
// 假设你有一个现有的四元数
Quaternion originalQuaternion = Quaternion.identity;
// 转换为30度旋转
Quaternion newQuaternion = rotate3 * originalQuaternion;
// 应用到游戏对象
this.transform.rotation = newQuaternion;
}
}
3.5 直接用Quaternion.AngleAxis *Quaternion.AngleAxis 实现同时绕着多轴旋转
- this.transform.rotation = Quaternion.AngleAxis (90.0f, transform.right) * Quaternion.AngleAxis (30.0f, transform.up);
- Quaternion.AngleAxis (90.0f, transform.right) // 绕着right轴X轴旋转90
- Quaternion.AngleAxis (30.0f, transform.up) // 绕着up轴y轴旋转30
- this.transform.rotation 可以实现连续旋转,不知道为啥上面的只能转1次
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class rotateTest1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
this.transform.rotation = Quaternion.AngleAxis (90.0f, transform.right) * Quaternion.AngleAxis (30.0f, transform.up);
}
}
3.6 直接用Quaternion.AngleAxis *Quaternion.AngleAxis 实现同时绕着多轴旋转
- 但是其中一个Quaternion 用欧拉角转化而来
- this.transform.rotation = Quaternion.Euler (new Vector3 (0.0f, 90.0f, 0.0f)) * Quaternion.AngleAxis (30.0f, transform.up);
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class rotateTest1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
this.transform.rotation = Quaternion.Euler (new Vector3 (0.0f, 90.0f, 0.0f)) * Quaternion.AngleAxis (30.0f, transform.up);
}
}
3.7 下面是完整的测试草稿代码
如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class rotateTest1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
//使用euler欧拉角旋转
//Vector3 rotate1 = new Vector3(0,30,0);
//this.transform.Rotate(rotate1);
//使用quaternion四元数,xyzw?
//Quaternion quaternion1 = new Quaternion(0,0,0,0);
//使用quaternion四元数,类 Vector3.zero 这种固定坐标了,固定的旋转?
//Quaternion quaternion2 = Quaternion.identity;
//利用unity编辑器,在unity里通过看向一个物体而实现旋转
//重新给quaternion2赋值
// quaternion2 = Quaternion.LookRotation(new Vector3(0,0,0));
///互转
//使用Euler转化为quaternion四元数
//quaternion2 = Quaternion.Euler(rotate1);
//使用quaternion四元数转化为Euler角
//给rotate2赋值,需要先定义rotate2
//Vector3 rotate2 = new Vector3(0,0,0);
//rotate2 = quaternion2.eulerAngles;
}
// Update is called once per frame
void Update()
{
//使用euler欧拉角旋转
//Vector3 rotate1 = new Vector3(0,30,0);
//使用quaternion四元数,w,xyz ,其中w是实数部分,xyz都是*i的虚数部分
//Quaternion quaternion1 = new Quaternion(0.866f,0,0,0.5f);
//quaternion1不能持续旋转这个方法?this.transform.Rotate(quaternion1);
//只能用this.transform.rotation 旋转到指定位置,而不能持续旋转
//this.transform.rotation = quaternion1;
//Quaternion quaternion1 = new Quaternion(0.866f,0,0,0.5f);
//Vector3 rotate2 = new Vector3(0,0,0);
//rotate2 = quaternion1.eulerAngles;
//this.transform.Rotate(rotate2);
// 创建一个表示xx度旋转欧拉角,然后转换为的四元数,表示绕Y轴旋转
//Quaternion rotate3 = Quaternion.Euler(0, 45, 0);
// 假设你有一个现有的四元数
//Quaternion originalQuaternion = Quaternion.identity;
// 转换为30度旋转
//Quaternion newQuaternion = rotate3 * originalQuaternion;
// 应用到游戏对象
//this.transform.rotation = newQuaternion;
// 多个四元数旋转操作相乘 *,然后转换为的四元数
//其中四元数也可以被替换为 欧拉角
this.transform.rotation = Quaternion.Euler (new Vector3 (0.0f, 90.0f, 0.0f)) * Quaternion.AngleAxis (30.0f, transform.up);
}
}
4 未解决的问题
4.1 不了解为啥上面有的时候可以持续旋转,有时候只能旋转1次
4.2 关于下面的匀速代码
- 不理解下面的匀速代码
- 不理解匀速代码下,为啥改速度没效果?改轴也没效果?
5 另外一种匀速代码
using UnityEngine;
public class RotateObject : MonoBehaviour
{
// 旋转速度,度/秒
public float speed = 30.0f;
// 旋转轴
public Vector3 axis = Vector3.right;
void Update()
{
// 计算旋转量
//Time.deltaTime 是上一帧的时间,可以实现不同机器的匀速播放效果
float angle = speed * Time.deltaTime;
// 绕axis轴旋转object
transform.Rotate(axis, angle);
}
}