首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐
2025年7月9日 星期三 0:48am

unity学习17:unity里的旋转学习,欧拉角,四元数等

  • 25-03-02 07:42
  • 4701
  • 6614
blog.csdn.net

目录

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-..._欧拉角和四元数的区别http://iyenn.com/rec/1690599.html

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/267359507icon-default.png?t=O83Ahttps://zhuanlan.zhihu.com/p/267359507

https://zhuanlan.zhihu.com/p/513687673icon-default.png?t=O83Ahttps://zhuanlan.zhihu.com/p/513687673

https://www.zhihu.com/question/23005815icon-default.png?t=O83Ahttps://www.zhihu.com/question/23005815

https://zhuanlan.zhihu.com/p/27471300icon-default.png?t=O83Ahttps://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;

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class rotateTest1 : MonoBehaviour
  5. {
  6. // Start is called before the first frame update
  7. void Start()
  8. {
  9. //使用euler欧拉角旋转
  10. Vector3 rotate1 = new Vector3(0,30,0);
  11. //使用quaternion四元数,xyzw?
  12. Quaternion quaternion1 = new Quaternion(0,0,0,0);
  13. //使用quaternion四元数,类 Vector3.zero 这种固定坐标了,固定的旋转?
  14. Quaternion quaternion2 = Quaternion.identity;
  15. //利用unity编辑器,在unity里通过看向一个物体而实现旋转
  16. //重新给quaternion2赋值
  17. quaternion2 = Quaternion.LookRotation(new Vector3(0,0,0));
  18. ///互转
  19. //使用Euler转化为quaternion四元数
  20. quaternion2 = Quaternion.Euler(rotate1);
  21. //使用quaternion四元数转化为Euler角
  22. //给rotate2赋值,需要先定义rotate2
  23. Vector3 rotate2 = new Vector3(0,0,0);
  24. rotate2 = quaternion2.eulerAngles;
  25. }
  26. // Update is called once per frame
  27. void Update()
  28. {
  29. }
  30. }

3 逐一测试旋转效果

3.1 直接使用Euler角Vector3(0,30,0)来旋转

    Vector3 rotate1 = new Vector3(0,30,0);

    this.transform.Rotate(rotate1);  

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class rotateTest1 : MonoBehaviour
  5. {
  6. // Start is called before the first frame update
  7. void Start()
  8. {
  9. }
  10. // Update is called once per frame
  11. void Update()
  12. {
  13. //使用euler欧拉角旋转
  14. Vector3 rotate1 = new Vector3(0,30,0);
  15. this.transform.Rotate(rotate1);
  16. }
  17. }

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;
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class rotateTest1 : MonoBehaviour
  5. {
  6. // Start is called before the first frame update
  7. void Start()
  8. {
  9. }
  10. // Update is called once per frame
  11. void Update()
  12. {
  13. //使用euler欧拉角旋转
  14. //Vector3 rotate1 = new Vector3(0,30,0);
  15. //使用quaternion四元数,w,xyz ,其中w是实数部分,xyz都是*i的虚数部分
  16. Quaternion quaternion1 = new Quaternion(0.866f,0,0,0.5f);
  17. //quaternion1不能持续旋转这个方法?this.transform.Rotate(quaternion1);
  18. //只能用this.transform.rotation 旋转到指定位置,而不能持续旋转
  19. this.transform.rotation = quaternion1;
  20. }
  21. }

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);  

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class rotateTest1 : MonoBehaviour
  5. {
  6. // Start is called before the first frame update
  7. void Start()
  8. {
  9. }
  10. // Update is called once per frame
  11. void Update()
  12. {
  13. Quaternion quaternion1 = new Quaternion(0.866f,0,0,0.5f);
  14. Vector3 rotate2 = new Vector3(0,0,0);
  15. rotate2 = quaternion1.eulerAngles;
  16. this.transform.Rotate(rotate2);
  17. }
  18. }

3.4 用欧拉角转成四元数后旋转

    // 创建一个表示xx度旋转欧拉角,然后转换为的四元数,表示绕Y轴旋转

    Quaternion rotate3 = Quaternion.Euler(0, 45, 0);

    // 假设你有一个现有的四元数

    Quaternion originalQuaternion = Quaternion.identity;

    // 转换为30度旋转

    Quaternion newQuaternion = rotate3 * originalQuaternion;

    // 应用到游戏对象

    this.transform.rotation = newQuaternion;

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class rotateTest1 : MonoBehaviour
  5. {
  6. // Start is called before the first frame update
  7. void Start()
  8. {
  9. }
  10. // Update is called once per frame
  11. void Update()
  12. {
  13. // 创建一个表示xx度旋转欧拉角,然后转换为的四元数,表示绕Y轴旋转
  14. Quaternion rotate3 = Quaternion.Euler(0, 45, 0);
  15. // 假设你有一个现有的四元数
  16. Quaternion originalQuaternion = Quaternion.identity;
  17. // 转换为30度旋转
  18. Quaternion newQuaternion = rotate3 * originalQuaternion;
  19. // 应用到游戏对象
  20. this.transform.rotation = newQuaternion;
  21. }
  22. }

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次

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class rotateTest1 : MonoBehaviour
  5. {
  6. // Start is called before the first frame update
  7. void Start()
  8. {
  9. }
  10. // Update is called once per frame
  11. void Update()
  12. {
  13. this.transform.rotation = Quaternion.AngleAxis (90.0f, transform.right)  *  Quaternion.AngleAxis (30.0f, transform.up);
  14. }
  15. }

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);

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class rotateTest1 : MonoBehaviour
  5. {
  6. // Start is called before the first frame update
  7. void Start()
  8. {
  9. }
  10. // Update is called once per frame
  11. void Update()
  12. {
  13. this.transform.rotation = Quaternion.Euler (new Vector3 (0.0f, 90.0f, 0.0f)) * Quaternion.AngleAxis (30.0f, transform.up);
  14. }
  15. }

3.7 下面是完整的测试草稿代码

如下

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class rotateTest1 : MonoBehaviour
  5. {
  6. // Start is called before the first frame update
  7. void Start()
  8. {
  9. //使用euler欧拉角旋转
  10. //Vector3 rotate1 = new Vector3(0,30,0);
  11. //this.transform.Rotate(rotate1);
  12. //使用quaternion四元数,xyzw?
  13. //Quaternion quaternion1 = new Quaternion(0,0,0,0);
  14. //使用quaternion四元数,类 Vector3.zero 这种固定坐标了,固定的旋转?
  15. //Quaternion quaternion2 = Quaternion.identity;
  16. //利用unity编辑器,在unity里通过看向一个物体而实现旋转
  17. //重新给quaternion2赋值
  18. // quaternion2 = Quaternion.LookRotation(new Vector3(0,0,0));
  19. ///互转
  20. //使用Euler转化为quaternion四元数
  21. //quaternion2 = Quaternion.Euler(rotate1);
  22. //使用quaternion四元数转化为Euler角
  23. //给rotate2赋值,需要先定义rotate2
  24. //Vector3 rotate2 = new Vector3(0,0,0);
  25. //rotate2 = quaternion2.eulerAngles;
  26. }
  27. // Update is called once per frame
  28. void Update()
  29. {
  30. //使用euler欧拉角旋转
  31. //Vector3 rotate1 = new Vector3(0,30,0);
  32. //使用quaternion四元数,w,xyz ,其中w是实数部分,xyz都是*i的虚数部分
  33. //Quaternion quaternion1 = new Quaternion(0.866f,0,0,0.5f);
  34. //quaternion1不能持续旋转这个方法?this.transform.Rotate(quaternion1);
  35. //只能用this.transform.rotation 旋转到指定位置,而不能持续旋转
  36. //this.transform.rotation = quaternion1;
  37. //Quaternion quaternion1 = new Quaternion(0.866f,0,0,0.5f);
  38. //Vector3 rotate2 = new Vector3(0,0,0);
  39. //rotate2 = quaternion1.eulerAngles;
  40. //this.transform.Rotate(rotate2);
  41. // 创建一个表示xx度旋转欧拉角,然后转换为的四元数,表示绕Y轴旋转
  42. //Quaternion rotate3 = Quaternion.Euler(0, 45, 0);
  43. // 假设你有一个现有的四元数
  44. //Quaternion originalQuaternion = Quaternion.identity;
  45. // 转换为30度旋转
  46. //Quaternion newQuaternion = rotate3 * originalQuaternion;
  47. // 应用到游戏对象
  48. //this.transform.rotation = newQuaternion;
  49. // 多个四元数旋转操作相乘 *,然后转换为的四元数
  50. //其中四元数也可以被替换为 欧拉角
  51. this.transform.rotation = Quaternion.Euler (new Vector3 (0.0f, 90.0f, 0.0f)) * Quaternion.AngleAxis (30.0f, transform.up);
  52. }
  53. }

4 未解决的问题

4.1 不了解为啥上面有的时候可以持续旋转,有时候只能旋转1次

4.2 关于下面的匀速代码

  • 不理解下面的匀速代码
  • 不理解匀速代码下,为啥改速度没效果?改轴也没效果?

5 另外一种匀速代码

  1. using UnityEngine;
  2. public class RotateObject : MonoBehaviour
  3. {
  4. // 旋转速度,度/秒
  5. public float speed = 30.0f;
  6. // 旋转轴
  7. public Vector3 axis = Vector3.right;
  8. void Update()
  9. {
  10. // 计算旋转量
  11. //Time.deltaTime 是上一帧的时间,可以实现不同机器的匀速播放效果
  12. float angle = speed * Time.deltaTime;
  13. // 绕axis轴旋转object
  14. transform.Rotate(axis, angle);
  15. }
  16. }

注:本文转载自blog.csdn.net的奔跑的犀牛先生的文章"https://blog.csdn.net/xuemanqianshan/article/details/145140212"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

134
游戏
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top