码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 四元数与其在Unity中的简单应用


    前置知识,能理解欧拉角的旋转过程和它的万向节死锁。

    一、四元数的基本介绍

    1.四元数的特点与缺点

    1)优点:
    可以避免万向节锁现象;
    只需要一个4维的四元数就可以执行绕任意过原点的向量的旋转,方便快捷,在某些实现下比旋转矩阵效率更高;
    可以提供平滑插值;
    2)缺点:
    比欧拉旋转稍微复杂了一点点,因为多了一个维度;
    理解更困难,不直观;

    接下来带着四元数的优点和缺点去理解四元数会更加有的放矢。

    2.四元数的基本运算规律

    1)这里面东西太多了,贴几个比较好的帖子大家去看看。

    四元数——基本概念 - 知乎

    https://krasjet.github.io/quaternion/quaternion.pdf

    四元数(Quaternions) - 知乎

    不过最推荐的还是这个,看着会比较舒服:图形学笔记 - 知乎

    2)大致总结一下比较重要的概念:

    四元数的虚部与实部、单位四元数、纯四元数、四元数的点积、乘积、叉积、四元数的共轭与逆、四元数表示旋转、四元数的插值。感觉这些概念看懂应该就算入门四元数了吧。

    3.能大致理解四元数运算的几何含义

    可以参考一下这个:https://jingyan.baidu.com/article/4ae03de3dbbac83eff9e6b00.html

    里面提出的四元数可以表示状态和动作的这种说法感觉很赞,对理解记忆四元数有帮助。

    二、四元数与欧拉角的相互转化

    这可以当成四元数的一个理论理解的练习,推导过于麻烦了,就直接贴出参考链接,这四个链接给出了不错的推导过程,需要注意的就是在unity中欧拉角的旋转顺序。

    三维旋转:欧拉角、四元数、旋转矩阵、轴角之间的转换 - 知乎

    四元数与欧拉角(RPY角)的相互转换 - XXX已失联 - 博客园

    四元数与欧拉角(Yaw、Pitch、Roll)的转换_xiaoma_bk的博客-CSDN博客_四元数与欧拉角

    Unity 四元数与欧拉角的相互转换及推导_晒网君的博客-CSDN博客_unity 欧拉角转四元数

    接下来我就直接贴出相互转化的测试代码了

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class QuaternionRotate : MonoBehaviour
    5. {
    6. void Start()
    7. {
    8. Quaternion q=Quaternion.Euler(60,60,60);
    9. Debug.Log("原始欧拉角 " + new Vector3(60, 60, 60));
    10. Debug.Log("原始四元数 "+q);
    11. Debug.Log("转换的欧拉角 " + QuaternionToEuler(q.x, q.y, q.z, q.w));
    12. Debug.Log("转换的四元数 " + EulerToQuaternion(60,60,60));
    13. }
    14. public Quaternion EulerToQuaternion(float xx, float yy, float zz)
    15. {
    16. float X = xx / 180 * Mathf.PI;
    17. float Y = yy / 180 * Mathf.PI;
    18. float Z = zz / 180 * Mathf.PI;
    19. float x = Mathf.Cos(Y / 2) * Mathf.Sin(X / 2) * Mathf.Cos(Z / 2) + Mathf.Sin(Y / 2) * Mathf.Cos(X / 2) * Mathf.Sin(Z / 2);
    20. float y = Mathf.Sin(Y / 2) * Mathf.Cos(X / 2) * Mathf.Cos(Z / 2) - Mathf.Cos(Y / 2) * Mathf.Sin(X / 2) * Mathf.Sin(Z / 2);
    21. float z = Mathf.Cos(Y / 2) * Mathf.Cos(X / 2) * Mathf.Sin(Z / 2) - Mathf.Sin(Y / 2) * Mathf.Sin(X / 2) * Mathf.Cos(Z / 2);
    22. float w = Mathf.Cos(Y / 2) * Mathf.Cos(X / 2) * Mathf.Cos(Z / 2) + Mathf.Sin(Y / 2) * Mathf.Sin(X / 2) * Mathf.Sin(Z / 2);
    23. Quaternion quataion = new Quaternion(x, y, z, w);
    24. return quataion;
    25. }
    26. public Vector3 QuaternionToEuler(float xx, float yy, float zz, float ww)
    27. {
    28. float X = Mathf.Asin(2 * (ww * xx - yy * zz));
    29. float Y = Mathf.Atan2(2 * (ww * yy + xx * zz), 1 - 2 * (xx * xx + yy * yy));
    30. float Z = Mathf.Atan2(2 * (ww * zz + yy * xx), 1 - 2 * (xx * xx + zz * zz));
    31. Vector3 euler = new Vector3(X * 180f / Mathf.PI, Y * 180f / Mathf.PI, Z * 180f / Mathf.PI);
    32. return euler;
    33. }
    34. }

     上面的EulerToQuaternion函数对应unity中的Quaternion.Euler函数,QuaternionToEuler函数对应unity中的q.eulerAngles函数。

    三、以Unity举例四元数的使用

    该部分主要参考自:

    【100个 Unity实用技能】| 游戏中使技能或装备跟随角色环绕,持续旋转_呆呆敲代码的小Y的博客-CSDN博客_unity 技能

    四元数主要就是旋转和旋转插值用,用下面的代码可以做出一个某个物体一直跟随另一个物体旋转(跟随旋转)的效果。

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class Saber : MonoBehaviour {
    5. public Transform targetPos;//旋转中心对象
    6. public float speed = 200f;//旋转速度
    7. public float distance;//旋转半径
    8. Vector3 dir;
    9. void Start()
    10. {
    11. dir = transform.position - targetPos.position;
    12. }
    13. void Update() {
    14. //更新跟随物体的位置
    15. transform.position = targetPos.position + dir.normalized * distance;
    16. //围绕角色旋转
    17. transform.RotateAround(targetPos.position, Vector3.up, speed * Time.deltaTime);
    18. //更新方向向量
    19. dir = transform.position - targetPos.position;
    20. }
    21. }

    参考RotateAround函数的源码,可以看出里面对四元数的使用。

    1. public void RotateAround(Vector3 point, Vector3 axis, float angle)
    2. {
    3. Vector3 vector = position;
    4. Quaternion quaternion = Quaternion.AngleAxis(angle, axis);
    5. Vector3 vector2 = vector - point;
    6. vector2 = quaternion * vector2;
    7. vector = (position = point + vector2);
    8. RotateAroundInternal(axis, angle * ((float)Math.PI / 180f));
    9. }

  • 相关阅读:
    PHP 使用 Guzzle 执行 HTTP 请求
    ChatGPT成知名度最高生成式AI产品,使用频率却不高
    alert、consloe、console.error、confirm、prompt
    Golang接口实现OCP原则
    万字长文硬核AQS源码分析
    Springboot毕设项目高校心理咨询系统y34td(java+VUE+Mybatis+Maven+Mysql)
    C语言共用体详解
    C++11改动
    听GPT 讲Rust源代码--library/core/src(7)
    必备表格软件-FineReport正则表达式简介
  • 原文地址:https://blog.csdn.net/qq_42987967/article/details/126034134
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号