【Unity学习笔记】第十七 Quaternion 中 LookRotation、Lerp、Slerp、RotateTowards等方法辨析与验证

转载请注明出处: https://blog.csdn.net/weixin_44013533/article/details/138909256

作者:CSDN@|Ringleader|

目录

    • Quaternion API 速览
    • FromToRotation在Transform中的应用
    • LookRotation 中upwards取Vector3.up和 transform.up的区别
    • 旋转时如何保持Y轴不变,但朝向目标旋转呢?
    • 不同旋转方法案例
    • lerp与LerpUnclamped区别
    • Quaternion.Slerp 、Quaternion.RotateTowards区别
    • Lerp、Slerp比较
    • Quaternion * operator
    • 总结

主要参考:

  1. Unity手册 & Quaternion API
  2. Unity3D - 详解Quaternion类(二)
  3. 【Unity编程】Unity中关于四元数的API详解

Quaternion API 速览

创建旋转:

  • FromToRotation 创建一个从 fromDirection 旋转到 toDirection 的旋转。
  • LookRotation 使用指定的 forward 和 upwards 方向创建旋转。
  • AngleAxis 创建一个围绕 axis 旋转 angle 度的旋转。
  • Angle 返回两个旋转 a 和 b 之间的角度(以度为单位)。(180°以内)

操作旋转:

  • Lerp 在 a 和 b 之间插入 t,然后对结果进行标准化处理。参数 t 被限制在 [0, 1] 范围内。
  • Slerp 在四元数 a 与 b 之间按比率 t 进行球形插值。参数 t 限制在范围 [0, 1] 内。
  • RotateTowards 将旋转 from 向 to 旋转。

Transform 类还提供了一些方法可用于处理 Quaternion 旋转:Transform.Rotate & Transform.RotateAround

FromToRotation在Transform中的应用

Transform中有很多Quaternion的应用,比如获取对象的xyz轴向量在世界坐标系下的表示,就用到了FromToRotation:

   ///<para>The red axis of the transform in world space.</para>public Vector3 right{get => this.rotation * Vector3.right;set => this.rotation = Quaternion.FromToRotation(Vector3.right, value);}///<para>The green axis of the transform in world space.</para>public Vector3 up{get => this.rotation * Vector3.up;set => this.rotation = Quaternion.FromToRotation(Vector3.up, value);}///<para>Returns a normalized vector representing the blue axis of the transform in world space.public Vector3 forward{get => this.rotation * Vector3.forward;set => this.rotation = Quaternion.LookRotation(value);}

LookRotation 中upwards取Vector3.up和 transform.up的区别

public static Quaternion LookRotation (Vector3 forward, Vector3 upwards= Vector3.up);

因为LookRotation 会使对象Z轴与forward参数向量对齐,X 轴与Vector3.Cross(upwards,forward)这个叉乘结果对齐,Y 轴与 Z 和 X 的叉乘(Vector3.Cross(transform.forward,transform.right) )对齐。(注意unity左手坐标系,叉乘方向)

所以会看到当upwards取世界空间的向上和模型空间的向上是有区别的。

或者说,upwards取模型空间的向上时对象可以绕自身z轴旋转,对象状态并不固定。
在这里插入图片描述

public class LookRotationTest : MonoBehaviour
{public Transform obt_forward;public Transform obt_worldUp;public Transform obt_selfUp;public bool showCrossResult = false;// 验证叉乘方向用private void Update(){// upwards取世界空间的向上LookForward(obt_worldUp, obt_forward.position - obt_worldUp.position, Vector3.up);// upwards取模型空间的向上LookForward(obt_selfUp,obt_forward.position - obt_selfUp.position, obt_selfUp.up);}private void LookForward(Transform obt, Vector3 forward,Vector3 upwards){obt.rotation = Quaternion.LookRotation(forward, upwards);var position = obt.position;Debug.DrawLine(obt_forward.position, position);Debug.DrawLine(position, position + obt.right * 5, Color.red);Debug.DrawLine(position, position + obt.up * 5, Color.green);Debug.DrawLine(position, position + obt.forward * 5, Color.blue);// 验证叉乘方向, 叉乘结果与LookFoward结果一致if (showCrossResult){var X_cross = Vector3.Cross(upwards,forward);var Y_cross = Vector3.Cross(obt.forward,obt.right);Debug.DrawLine(position, position + X_cross * 10, Color.cyan);Debug.DrawLine(position, position + Y_cross * 10, Color.yellow);}}
}

旋转时如何保持Y轴不变,但朝向目标旋转呢?

使用Vector3.ProjectOnPlane将目标方向投影到xz平面。
在这里插入图片描述

Lookat, FromToRotation and LookRotation?

不同旋转方法案例

下面代码比较了transform.forward 、Transform.LookAt、Quaternion.FromToRotation、LookRotation、Quaternion.RotateTowards、Vector3.ProjectOnPlane等不同方法

public class CompareImmediateAndStep : MonoBehaviour
{public Transform turret;public Transform enemy;private string str;private void Update(){var targetTowards = enemy.position - turret.position;// 立刻跟随敌人if (Input.GetKey(KeyCode.Alpha1)){turret.forward = targetTowards;str = "使用turret.forward = targetTowards;";}// 上面本质也是使用FromToRotation方法if (Input.GetKey(KeyCode.Alpha2)){turret.rotation = Quaternion.FromToRotation(Vector3.forward, targetTowards);str = "使用turret.rotation = Quaternion.FromToRotation(Vector3.forward, targetTowards);";}if (Input.GetKey(KeyCode.Alpha3)){//当FromToRotation的fromDirection参数是forward轴时,可以用LookRotationturret.rotation = Quaternion.LookRotation(targetTowards);str = "turret.rotation = Quaternion.LookRotation(targetTowards);";}if (Input.GetKey(KeyCode.Alpha4)){turret.LookAt(enemy.transform);str = "turret.LookAt(enemy.transform);";}// 插值方式,加入旋转速度if (Input.GetKey(KeyCode.Alpha5)){var fromToRotation = Quaternion.LookRotation(targetTowards);turret.rotation = Quaternion.RotateTowards(turret.rotation, fromToRotation, 45 * Time.deltaTime);str = "使用worldUp的Quaternion.RotateTowards";}// 保持对象Y轴朝向不变,将targetTowards进行投影if (Input.GetKey(KeyCode.Alpha6)){var fromToRotation = Quaternion.LookRotation(Vector3.ProjectOnPlane(targetTowards,Vector3.up),Vector3.up);turret.rotation = Quaternion.RotateTowards(turret.rotation, fromToRotation, 45 * Time.deltaTime);str = "保持Y轴朝向不变,将targetTowards进行投影";}DrawAxis(turret);DrawAxis(enemy);}private void DrawAxis(Transform obt){DrawAxis(obt, Color.red, Color.green, Color.blue, 5);}private void DrawAxis(Transform obt, Color xc, Color yc, Color zc, float length){if (obt.gameObject.activeInHierarchy){var position = obt.position;Debug.DrawLine(position, position + obt.right * length, xc);Debug.DrawLine(position, position + obt.up * length, yc);Debug.DrawLine(position, position + obt.forward * length, zc);}}private Rect rect = new Rect(100, 100, 600, 50);private void OnGUI(){DrawLabel(rect, str);}private static void DrawLabel(Rect rect1, String str){var style = new GUIStyle{fontSize = 38,wordWrap = true};GUI.Label(rect1, str, style);}
}

lerp与LerpUnclamped区别

区别就是Unclam不会钳值,而且取负数时会从to→from旋转。
在这里插入图片描述

Vector3: Lerp vs LerpUnclamped

Quaternion.Slerp 、Quaternion.RotateTowards区别

RotateTowards本质也是使用了SlerpUnclamped方法,但其旋转速度恒定,不会因target变化而改变。

public static Quaternion RotateTowards(Quaternion from, Quaternion to, float maxDegreesDelta){float num = Quaternion.Angle(from, to);return (double) num == 0.0 ? to : Quaternion.SlerpUnclamped(from, to, Mathf.Min(1f, maxDegreesDelta / num));}

这篇帖子 Use Quaternion.RotateTowards() instead of Quaternion.Slerp() 提到了:

如果旋转操作的from和to都已知,使用 Quaternion.Slerp() - 例如打开一扇门或箱子盖。
如果要以恒定角速度转向某物,则使用 Quaternion.RotateTowards() - 例如,在塔防类游戏中要转向塔的炮塔。

Lerp、Slerp比较

Quaternion的插值分析及总结
Lerp求得的是四元数在圆上的弦上的等分,而Slerp求得的是四元数载圆上的圆弧的等分
在这里插入图片描述

进行代码验证:

public class SlerpTest : MonoBehaviour
{public Transform obtLerp;public Transform obtSlerp;public Transform towardsObt;public bool towardsNotChanged;private Quaternion currentLookRotation,lastLookRotation;private Quaternion initRotationLerp, initRotationSlerp;public float speed = 0.1f;float total = 0.0f;private void Start(){lastLookRotation = Quaternion.LookRotation(towardsObt.position-obtLerp.position);initRotationLerp = obtLerp.rotation;initRotationSlerp = obtSlerp.rotation;}void Update(){CompareSlerpAndLerp();}private void CompareSlerpAndLerp(){currentLookRotation = Quaternion.LookRotation(towardsObt.position - obtLerp.position);towardsNotChanged = currentLookRotation == lastLookRotation;// 改变朝向时,重置初始位置、重置totalif (!towardsNotChanged){lastLookRotation = currentLookRotation;// 重置执行Lerp、Slerp时的初始旋转initRotationLerp = obtLerp.rotation;initRotationSlerp = obtSlerp.rotation;total = 0;return;}lastLookRotation = currentLookRotation;total += Time.deltaTime * speed;if (total >= 1.0f)total = 1.0f;obtLerp.rotation = Quaternion.Lerp(initRotationLerp, currentLookRotation, total);obtSlerp.rotation = Quaternion.Slerp(initRotationSlerp, currentLookRotation, total);DrawAxis(obtLerp);DrawAxis(obtSlerp, Color.cyan, Color.magenta, Color.yellow, 10);}private void DrawAxis(Transform obt){DrawAxis(obt, Color.red, Color.green, Color.blue, 5);}private void DrawAxis(Transform obt,Color xc,Color yc,Color zc,float length){if (obt.gameObject.activeInHierarchy){var position = obt.position;Debug.DrawLine(position, position + obt.right * length, xc);Debug.DrawLine(position, position + obt.up * length, yc);Debug.DrawLine(position, position + obt.forward * length, zc);}}private Rect rect = new Rect(100, 100, 600, 50);private void OnGUI(){DrawLabel(rect,"Total:"+total);}private void DrawLabel(Rect rect1, String str){var style = new GUIStyle{fontSize = 38,wordWrap = true};GUI.Label(rect1, str, style);}
}

如下图,RGB颜色的轴是Lerp方法,青紫黄轴是Slerp方法。可以看到Lerp相对Slerp来说先慢,中间快,最后慢。和上面的弦等分和弧等分理论一致。
请添加图片描述

Quaternion * operator

在这里插入图片描述
关于Quaternion 左乘右乘和坐标系的关系看我这篇:【Unity学习笔记】第十六 World space、Parent space和Self space及Quaternion左乘右乘辨析

总结

本文主要辨析Quaternion中Lerp、Slerp、RotateTowards等方法,并进行代码验证。至此,对Quaternion核心方法的理解已比较清晰,但其中的数学原理比如四元数、和欧拉角的关系、万向锁、逆和共轭等问题还是有待进一步学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/13069.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

战网国际服怎么下载 暴雪战网一键下载安装图文教程

战网国际版&#xff0c;或称为Battle.net全球版&#xff0c;是暴雪娱乐构建的一项跨越国界的综合游戏交流平台&#xff0c;它无视地理限制&#xff0c;旨在服务全球每一个角落的游戏爱好者。不同于地区专属版本&#xff0c;国际版为玩家开启了一扇无门槛的大门&#xff0c;让每…

org.springframework.jdbc.BadSqlGrammarException

Cause: java.sql.SQLSyntaxErrorException: Table ‘web.emp’ doesn’t exist 产生原因&#xff1a;web表找不到&#xff0c;所以可能数据库配置错误 spring.datasource.urljdbc:mysql://localhost:3306/web02 更改完成后运行成功

免费利器:会议之眼一键生成论文功能火爆上线 助你快速起航

会议之眼 快讯 亲爱的会议之眼粉丝们&#xff0c;你们是否曾经为了写论文而彻夜苦思冥想&#xff1f;是否曾经为了找资料而焦头烂额&#xff1f; 今天小编带来了一个令人兴奋的消息&#xff0c;那就是会议之眼网页端平台的全新功能——“一键生成论文”已经重磅上线啦&#x…

【计算机毕业设计】springboot房地产销售管理系统的设计与实现

相比于以前的传统手工管理方式&#xff0c;智能化的管理方式可以大幅降低房地产公司的运营人员成本&#xff0c;实现了房地产销售的 标准化、制度化、程序化的管理&#xff0c;有效地防止了房地产销售的随意管理&#xff0c;提高了信息的处理速度和精确度&#xff0c;能够及时、…

STM32-09-IWDG

文章目录 STM32 IWDG1. IWDG2. IWDG框图3. IWDG寄存器4. IWDG寄存器操作步骤5. IWDG溢出时间计算6. IWDG配置步骤7. 代码实现 STM32 IWDG 1. IWDG IWDG Independent watchdog&#xff0c;即独立看门狗&#xff0c;本质上是一个定时器&#xff0c;这个定时器有一个输出端&#…

mmdetection训练(1)voc格式的数据集(自制)

mmdetection训练&#xff08;1&#xff09;voc格式的数据集&#xff08;自制&#xff09; 提前准备一、voc数据集二、修改配置代码进行训练&#xff08;敲黑板&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff09;1.数据集相关内容修改2.自定义配置文件构…

云曦实验室期中考核题

Web_SINGIN 解题&#xff1a; 点击打开环境&#xff0c;得 查看源代码&#xff0c;得 点开下面的超链接&#xff0c;得 看到一串base64编码&#xff0c;解码得flag 简简单单的文件上传 解题&#xff1a; 点击打开环境&#xff0c;得 可以看出这是一道文件上传的题目&#x…

【if条件、for循环、数据框连接、表达矩阵画箱线图】

编程能力&#xff0c;就是解决问题的能力&#xff0c;也是变优秀的能力 From 生物技能树 R语言基础第七节 文章目录 1.长脚本管理方式if(F){....}分成多个脚本&#xff0c;每个脚本最后保存Rdata&#xff0c;下一个脚本开头清空再加载 2.实战项目的组织方式方法&#xff08;一&…

圆上点云随机生成(人工制作模拟数据)

1、背景介绍 实际上,很多地物外表形状满足一定的几何形状结构,如圆形是作为常见一类。那么获取该类目标的点云数据便是位于一个圆上的点云数据。如下图所示为两簇典型的点云,其中一种为理想型,点均位于一个圆上,另外一簇则是近似位于一个圆上,这种更加符合真实情况。有时…

好烦啊,我真的不想写增删改查了!

大家好&#xff0c;我是程序员鱼皮。 很想吐槽&#xff1a;我真的不想写增删改查这种重复代码了&#xff01; 大学刚做项目的时候&#xff0c;就在写增删改查&#xff0c;万万没想到 7 年后&#xff0c;还在和增删改查打交道。因为增删改查是任何项目的基础功能&#xff0c;每…

性能测试工具—jmeter的基础使用

1.Jmeter三个重要组件 1.1线程组的介绍&#xff1a; 特点&#xff1a; 模拟用户&#xff0c;支持多用户操作多个线程组可以串行执行&#xff0c;也可以并行执行 线程组的分类&#xff1a; setup线程组&#xff1a;前置处理&#xff0c;初始化普通线程组&#xff1a;编写…

springboot+vue+mybatis物业管理系统+PPT+论文+讲解+售后

快速发展的社会中&#xff0c;人们的生活水平都在提高&#xff0c;生活节奏也在逐渐加快。为了节省时间和提高工作效率&#xff0c;越来越多的人选择利用互联网进行线上打理各种事务&#xff0c;通过线上物业管理系统也就相继涌现。与此同时&#xff0c;人们开始接受方便的生活…

怎样让猫给啥吃啥?生骨肉冻干拌粮哪有猫咪不吃的!

随着科学养猫的普及&#xff0c;生骨肉冻干喂养越来越受欢迎&#xff0c;生骨肉冻干喂养对猫的好处很多&#xff0c;它符合猫咪的天性&#xff0c;可以提供全面的营养&#xff0c;保持牙齿和牙龈的健康&#xff0c;还有助于维持健康的消化系统。然而&#xff0c;许多猫主人在选…

考研操作系统-1.计算机系统概述

目录 操作系统功能 操作系统的发展与分类 操作系统的运行环境 操作系统的体系结构 王道考研操作系统-1.计算机系统概述 操作系统 是指控制和管理整个计算机系统的硬件和软件资源&#xff0c;合理地组织调度计算机的工作和资源的分配&#xff1b;提供给用户和软件方便的接…

GDPU 竞赛技能实践 天码行空 期末小测

1. 除法&#xff08;原题&#xff09; &#x1f468;‍&#x1f3eb; 实验二&#xff1a;1.简单枚举 输入正整数n&#xff0c;按从小到大的顺序输出所有形如abcde/fghij n的表达式&#xff0c;其中a&#xff5e;j恰好为数字0&#xff5e;9的一个排列&#xff08;可以有前导0&a…

复杂json解析(其中有一个key的value是json格式的字符串)

app上报的参数如下: {"clientId": "8517895440514039afcf6d3e5d7832ae","dua": "SNDOCKCJPH90_GA&VN900042418&BN0&VCXiaomi&MOM2012K11AC&RL1080_2239&CHIDunknown_unknown&LCID&RV&OSAndroid13&…

邦注科技 即热式节能模温机的原理及应用介绍

模温机是一种用于控制模具温度的设备&#xff0c;它在各种工业领域中发挥着重要作用&#xff0c;特别是在塑料加工行业中。以下是关于模温机的原理及应用的详细介绍&#xff1a; 原理 模温机的工作原理主要是通过加热和冷却功能&#xff0c;维持模具温度在一个恒定的范围内。…

Hadoop 3.4.0 项目实战

1环境基于 上一篇搭建 高可用分布式集群 2 官方提供MapReduce程序 #评估圆周率 cd /data/hadoop/share/hadoop/mapreduce/ hadoop jar hadoop-mapreduce-examples-3.4.0.jar pi 2 6 3 实例项目分析1 #预分析的文件如&#xff0c;如单词统计 # #上传文件到hdfs hdfs …

SOLIDWORKS 2024云服务新功能

一、简单的分享一下&#xff0c;在线观看&#xff0c;轻松标记 在达索系统SOLIDWORKS 2024云服务中&#xff0c;您只需在达索系统SOLIDWORKS中点击按钮&#xff0c;就可以将当前的设计分享给其他人&#xff0c;无论是客户、供应商还是团队内部成员。共享的用户只要打开浏览器里…

一本专业130+总分400+上海交通大学819考研经验上交电子信息与通信工程上岸,真题,大纲,参考书。

今年专业课819信号系统与信号处理130&#xff0c;总分400&#xff0c;复试表现中规中矩&#xff08;初试分数查到才开始复习复试&#xff0c;希望大家汲取教训&#xff0c;初试考完就可以录取开始准备复试&#xff09;&#xff0c;交大初试比重很高&#xff0c;良心学校&#x…