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

server/2025/1/16 7:21:29/

目录

1 三维空间里的旋转与欧拉角,四元数

1.1 欧拉角比较符合直观

1.2 四元数

1.3 下面是欧拉角和四元数的一些参考文章

2 关于旋转的这些知识点

2.1 使用euler欧拉角旋转

2.2 使用quaternion四元数,w,x,y,z

2.3 使用quaternion四元数,类 Vector3.zero 这种固定坐标了,固定的旋转?

unity%E7%BC%96%E8%BE%91%E5%99%A8%EF%BC%8C%E5%9C%A8unity%E9%87%8C%E9%80%9A%E8%BF%87%E7%9C%8B%E5%90%91%E4%B8%80%E4%B8%AA%E7%89%A9%E4%BD%93%E8%80%8C%E5%AE%9E%E7%8E%B0%E6%97%8B%E8%BD%AC-toc" style="margin-left:40px;">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;

unity%E7%BC%96%E8%BE%91%E5%99%A8%EF%BC%8C%E5%9C%A8unity%E9%87%8C%E9%80%9A%E8%BF%87%E7%9C%8B%E5%90%91%E4%B8%80%E4%B8%AA%E7%89%A9%E4%BD%93%E8%80%8C%E5%AE%9E%E7%8E%B0%E6%97%8B%E8%BD%AC">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 updatevoid 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赋值,需要先定义rotate2Vector3 rotate2 = new Vector3(0,0,0);rotate2 = quaternion2.eulerAngles;}// Update is called once per framevoid 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 updatevoid Start(){}// Update is called once per framevoid 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 updatevoid Start(){}// Update is called once per framevoid 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 updatevoid Start(){}// Update is called once per framevoid 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 updatevoid Start(){}// Update is called once per framevoid 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 updatevoid Start(){}// Update is called once per framevoid 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 updatevoid Start(){}// Update is called once per framevoid 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 updatevoid 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 framevoid 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轴旋转objecttransform.Rotate(axis, angle);}
}


http://www.ppmy.cn/server/158763.html

相关文章

SQL美化器优化

文章目录 1.目录2.代码 1.目录 2.代码 package com.sunxiansheng.mybatis.plus.inteceptor;import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.*; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.*…

云产品评测|阿里云服务诊断

文章目录 关于云服务诊断快速使用诊断功能诊断的定义诊断的意义诊断操作 建议与优化 大家好我是令狐,一名软件研发工程师。今天给大家介绍阿里云服务的诊断工具使用与体会,如果你也在使用阿里云服务,这会大大节省你定位问题的效率&#xff0c…

QT窗口阴影+拖动

QT 去除默认边框&#xff0c;为界面添加阴影&#xff0c;实现拖动效果。只是示例&#xff0c;没有完成关闭等按钮&#xff0c;根据具体情况添加&#xff0c;可以使用ui设计画一个。 #include <QApplication> #include <QWidget> #include <QPoint> #include…

【微服务justsoso-cloud系列】目录

【微服务justsoso-cloud系列】目录 1.vagrantvirtualbox实现centos7安装 2.centos7安装jdk17教程 3.Linux安装Docker教程&#xff08;详解&#xff09; 4.Linux安装git 5.zerotier搭建虚拟局域网&#xff0c;自建planet

如何优化Elasticsearch大文档查询?

记录一次业务复杂场景下DSL优化的过程 背景 B端商城业务有一个场景就是客户可见的产品列表是需要N多闸口及各种其它逻辑组合过滤的&#xff0c;各种闸口数据及产品数据都是存储在ES的(有的是独立索引&#xff0c;有的是作为产品属性存储在产品文档上)。 在实际使用的过程中&a…

【SQL——结构化查询语句】

数据的存储-SQL 数据的计算-Python 数据库是用来存储数据的&#xff0c;在这个过程中&#xff0c;会涉及到数据的增删改查与数据库数据表的维护管理 而SQL语言&#xff0c;就是一种对数据库、数据进行操作、管理、查询的工具。 使用数据库软件去获得库->表->数据&#x…

抖音矩阵是什么

抖音矩阵是指在同一品牌或个人IP下&#xff0c;通过创建多个不同定位的抖音账号&#xff08;如主号、副号、子号等&#xff09;&#xff0c;形成一个有机的整体&#xff0c;以实现多维度、多层次的内容覆盖和用户互动。以下是关于抖音矩阵的详细介绍&#xff1a; 抖音矩阵的类…

多态(2)

大家好&#xff0c;今天我们继续来学习多态的知识&#xff0c;上篇我们已经简单了解了多态&#xff0c;今天我们来看看该如何实现多态&#xff0c;来看。 重载和重写的区别是什么&#xff1f; 重载: 1.方法名称相同 2.参数列表不同[(数据类型,个数.顺序)] 3.返回值不做要…