当前位置: 首页 > article >正文

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

目录

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

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


http://www.kler.cn/a/503438.html

相关文章:

  • Unreal Engine 5 C++ Advanced Action RPG 八章笔记
  • STM32入门教程-示例程序(按键控制LED光敏传感器控制蜂鸣器)
  • 极客说|Azure AI Agent Service 结合 AutoGen/Semantic Kernel 构建多智能体解决⽅案
  • ElasticSearch在Windows环境搭建测试
  • js:根据后端返回数据的最大值进行计算然后设置这个最大值为百分之百,其他的值除这个最大值
  • VUE3 自定义指令的介绍
  • 登录、注册、忘记密码、首页HTML模板
  • 【Linux】9.Linux第一个小程序进度条
  • Ubuntu安装K8S
  • 【Uniapp-Vue3】组件中emit的声明触发事件
  • 华为数通-访问控制列表
  • 网络安全的几种攻击方法
  • 【数据仓库】— 5分钟浅谈数据仓库(适合新手)从理论到实践
  • IOday6互斥和同步
  • 《拉依达的嵌入式\驱动面试宝典》—操作系统篇(七)
  • 完全二叉树的顺序存储【堆】
  • [c#] 度分秒和度的转换
  • 轨迹优化 | 基于贝塞尔曲线的无约束路径平滑与粗轨迹生成(附ROS C++/Python仿真)
  • 嵌入式系统中的 OpenCV 与 OpenGLES 协同应用
  • 【C】初阶数据结构3 -- 单链表
  • maven高级(day15)
  • 安装虚拟机VMware遇到的问题
  • JAVA安全编码规范
  • 七 rk3568 android 11 ec20 4G驱动移植
  • EasyControl:首个登陆AWS Marketplace的中国MDM先锋
  • electron 上怎么用node 调用 c++ 提供的方法