Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >四元数到达万向节锁

四元数到达万向节锁
EN

Stack Overflow用户
提问于 2015-02-27 16:52:13
回答 2查看 8.1K关注 0票数 12

为了避免旋转时的角度锁定,我尝试切换到四元数。不知怎么的,我还在设法找到万向节锁。

我不确定是由于我实现的数学,还是设计错误,所以请指出我是否应该改变我的对象坐标的方法。

我的每个对象都持有一个X,Y,Z值,以及一个俯仰,偏航,滚动值。当我更改旋转值时,对象将根据上述信息重新计算其顶点。这一逻辑如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    // vertex array
    vertices[x] -= /*Offset by origin point*/;

    // Quat.'s representing rotation around xyz axes
    Quaternion q1 = Quaternion(glm::vec3(1,0,0),pitch);
    Quaternion q2 = Quaternion(glm::vec3(0,1,0),yaw); 
    Quaternion q3 = Quaternion(glm::vec3(0,0,1),roll); 

    // total rotation
    Quaternion TotalRot = ( (q3 * q2) * (q1) ); 

    // conversion of original coordinates to quaternion
    Quaternion Point1 = Quaternion(0, vertices[x].x(), vertices[x].y(), vertices[x].z()); 

    // resulting rotated point
    Quaternion Point2 = Quaternion( (TotalRot * Point1) * TotalRot.inverse() );

    // placing new point back into vertices array
    vertices[x] = QVector3D(round(Point2.v.x),round(Point2.v.y),round(Point2.v.z));
    vertices[x]+= /*Undo origin point offset*/;

"vertices[]“是对象顶点数组。上面注释掉的原点偏移量只是为了使对象围绕适当的原点旋转,因此相对于0,0,0,0,0,0,0,0,0,因为旋转发生在该点附近(对吗?)

我对我的问题有一个形象的描述,我首先偏航90度,俯仰45度,然后-90滚动,但滚动轴变得平行于俯仰轴:

编辑:

我试着把这3轴四元数相乘,然后乘以4x4矩阵,然后乘以顶点点,但我仍然把万向节锁/到达奇点相乘!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    Quaternion q1 = (1,0,0,pitch);
    Quaternion q2 = (0,1,0,yaw);
    Quaternion q3 = (0,0,1,roll);
    Quaternion qtot = (q1*q2)*q3;
    Quaternion p1(0, vertices[x].x(), vertices[x].y(), vertices[x].z());
    QMatrix4x4 m;
    m.rotate(qtot);
    QVector4D v = m*p1;
    vertices[x] = QVector3D(v.x(),v.y(),v.z());
EN

回答 2

Stack Overflow用户

发布于 2015-06-21 09:17:51

您的问题是,即使使用四元数,您仍然存储三个螺距、偏航和滚动值,而不是四元数,以表示对象的方向。

下面是使用四元数进行旋转的方法:

  1. 不是存储每个对象的X、Y、Z、螺距、偏航、滚动,而是在每个对象中存储X、Y、Z、orientation,其中orientation是从初始值(0、0、0、1)开始的四元数,意思是没有旋转。存储每个对象的俯仰、偏航和滚动容易受到奇点(万向节锁)的影响,因为当添加小的变化时,中间的一个旋转(例如,一个螺距)可能导致该对象平行于一个旋转轴(例如,偏航轴),因此围绕该轴的下一个旋转可能失败。
  2. 然后,当对象被旋转时,确定在该帧中发生的对象的音调、偏航和滚动(假设您的输入设备以该形式提供旋转),将其转换为四元数,然后将该四元数预乘为对象的orientation四元数。这种方法不太容易受到奇点的影响,因为预计每一帧的旋转变化都很小。
  3. 更改方向后,不要直接修改对象的X、Y和Z( verticies数组)。相反,当对象的方向发生变化时,创建一个新的旋转矩阵作为对象的世界转换矩阵的一部分(以及缩放和平移;要获得最佳结果,请将世界转换计算为translation * rotation * scaling)。
  4. 每隔几个帧,您就应该对orientation四元数进行规范化,以避免由于舍入错误而导致的方向上的不适当的更改。
票数 12
EN

Stack Overflow用户

发布于 2015-02-27 17:28:44

如果你用一个欧拉角表示并把它转换成四元数,仅仅是为了做向量旋转,那么你仍然只是使用欧拉角。只要你在任何地方都有欧拉角,万向节锁定问题就会继续存在。你需要完全切换到四元数,如果你想要完全消除这个问题的话,永远不要在任何地方进行欧拉角表示。

这样做的基本方法是,您可以在计算的远端使用Euler角(作为原始输入或最终输出),如果这对您更方便的话(例如,Euler角通常是一种“人类可读性”的表示)。但是,将四元数用于其他一切(您可以偶尔将其转换为旋转矩阵,因为它们对于旋转向量更有效),并且从不对任何“坏”的旋转表示(欧拉角、轴角等)进行中间转换。“万向无锁”的四元数和旋转矩阵的好处,只有当你坚持这两个表示在你的所有计算。

因此,一方面,您有奇异表示( "gimbal锁“的正式术语是奇点):

  • 欧拉角(顺便说一句,有12种);以及
  • 轴角

在另一边,你有一个没有奇异性的表示:

  • 四元数(更有效的内存和组合运算);以及
  • 旋转矩阵(更有效地将旋转应用于向量)。

每当您使用奇异表示操作(比如将几个旋转集合在一起,或移动一个旋转对象)时,您将不得不在每次计算中都担心这种奇异性。当你用奇点无关表示做同样的操作时,你就不用担心这个问题了(但是你必须担心约束,这是四元数的单位范数约束,旋转矩阵的适当正交性)。当然,任何时候,当你转换到或从一个奇异表示,你必须担心奇点。这就是为什么你只应该在你的计算的远端进行转换(当你进入或离开时),并且在你的计算中坚持使用非奇异表示。

欧拉角的唯一好用途是为了人类的可读性,周期。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28776788

复制
相关文章
将SSRF升级为RCE
今天我照例要和大家分享一个新的多汁漏洞。 这个问题是在一个私人客户中发现的,所以我们称之为redacted.com。 探索范围。 在列举客户的域为子域的时候,我发现子域[docs]。我发现子域[docs]。 我出来到这个子域[docs.redact.com]。 寻找带外资源负载。 [docs]子域显示了一些文件和统计资料。 当点击一个统计的照片时,我看到了一种奇怪的,但不是一个神奇的链接: 我首先想到的是把[url]的值改为generaleg0x01.com 然后我注意到了[mimeType]参数,所以编辑
Khan安全团队
2021/01/11
2K0
将SSRF升级为RCE
C# 利用.NET 升级助手将.NET Framework项目升级为.NET 6
.NET6 正式版本已经发布有一阵子了,今天我就体验一下如何将.NET Framework的项目升级为.NET 6.
用户9127601
2022/04/19
3.2K0
C# 利用.NET 升级助手将.NET Framework项目升级为.NET 6
使用 .NET 升级助手将NET Core 3.1项目升级为.NET 6
安装升级助手很简单,跟着这个教程开始 https://dotnet.microsoft.com/zh-cn/platform/upgrade-assistant/tutorial/intro:
张善友
2022/06/12
9160
Impala升级为Apache顶级项目
五年前,Cloudera向全世界分享了一个愿景,将通过一个新的SQL引擎Apache Impala(全球第一个也是Hadoop之上最快的MPP SQL引擎)将数十年关系型数据库研究的经验转移到Apache Hadoop平台之上,参考:
Fayson
2018/03/29
9580
Impala升级为Apache顶级项目
KubeVirt升级为CNCF孵化项目
CNCF 技术监督委员会[1](TOC,Technical Oversight Committee)已经投票接受 KubeVirt 作为 CNCF 的孵化项目。
CNCF
2022/06/10
7960
KubeVirt升级为CNCF孵化项目
如何将ubuntu LTS升级为Pro
将被升级的软件包,由 4 个(需要下载 98.9 MB),变为 59 个(需要下载 150 MB)。
zhangrelay
2023/07/27
1.6K0
如何将ubuntu LTS升级为Pro
勒索软件升级,运营模式升级为“三重勒索”
近期沸沸扬扬的、针对Colonial Pipeline发起攻击的勒索软件被FBI确认由DarkSide负责。DarkSide运营着勒索软件即服务(Raas),和许多合作伙伴协作进行攻击,共享赎金收益。
FB客服
2021/07/02
4540
手工将项目升级至 Angular 9 记录
Angular 最近发布了 9.0 版本, 需要先将一个模板项目升级至新版本。 虽然它提供了 ng update 命令来升级, 但是这个命令会自动调整 package.json 文件依赖项的顺序, 导致向其它项目合并时产生不必要的冲突。 为了不打乱现有的依赖项的顺序, 容易向其它派生项目进行合并, 同时也能明确知道究竟那些文件需要修改, 因此采用手工升级的办法。
beginor
2020/08/10
1.8K0
如何将单 master 升级为多 master 集群
前面我们课程中的集群是单 master 的集群,对于生产环境风险太大了,非常有必要做一个高可用的集群(https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/ha-topology/),这里的高可用主要是针对控制面板来说的,比如 kube-apiserver、etcd、kube-controller-manager、kube-scheduler 这几个组件,其中 kube-controller-manager 于 kube-scheduler 组件是 Kubernetes 集群自己去实现的高可用,当有多个组件存在的时候,会自动选择一个作为 Leader 提供服务,所以不需要我们手动去实现高可用,apiserver 和 etcd 就需要手动去搭建高可用的集群的。
我是阳明
2020/09/14
3.4K0
如何将单 master 升级为多 master 集群
Packer 如何将 JSON 的配置升级为 HCL2
在新版本的 Packer 中,如果你需要创建服务器的镜像的话,推荐使用 HCL2 的配置文件。
HoneyMoose
2021/06/24
9640
Packer 如何将 JSON 的配置升级为 HCL2
将React项目从webpack升级到Vite
点击上方“魔术师卡颂”,选择“设为星标” 专注React,学不会你打我! 在之前,已经很多朋友已经升级到了vite,但是大部分都是vue的项目,那么今天我们把之前webpack的react项目升级到
公众号@魔术师卡颂
2021/05/08
3.2K0
将React项目从webpack升级到Vite
将Spring Cloud项目改造为Spring-cloud-kubernetes项目
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/06/13
1.8K0
将Spring Cloud项目改造为Spring-cloud-kubernetes项目
Java设计模式之适配器设计模式(项目升级案例)
 今天是我学习到Java设计模式中的第三个设计模式了,但是天气又开始变得狂热起来,对于我这个凉爽惯了的青藏人来说,又是非常闹心的一件事儿,好了不管怎么样,目标还是目标(争取把23种Java设计模式接触一遍),我在北京向各位问好。老规矩,首先和各位谈谈适配器模式到底是个什么样的设计思想,而且在实际开发中又是如何应用的。        那些官方的概念我就不在这儿粘贴了,请各位自己想想办法。所谓适配器模式,按我意思说吧,其实它的目的就想达到新老兼容,使把原本不能放在一块工作的类或对象能够让它们同时使用起来,举个
赵小忠
2018/01/24
1.2K0
自动将 NuGet 包的引用方式从 packages.config 升级为 PackageReference
发布于 2018-04-24 10:03 更新于 2018-06-29 08:52
walterlv
2018/09/18
1.8K0
自动将 NuGet 包的引用方式从 packages.config 升级为 PackageReference
【1/25】将Game改写为单例模式(Singleton Pattern)
Game的实例在游戏时只有一个,现在我们首先将Game类改造为一个单例。所谓单例,就是运行时只有一个实例。Game.js代码改造如下:
LIYI
2021/02/23
4500
(四) 如何将socket设置为非阻塞模式
1. windows平台上无论利用socket()函数还是WSASocket()函数创建的socket都是阻塞模式的: SOCKET WSAAPI socket( _In_ int af, _In_ int type, _In_ int protocol ); SOCKET WSASocket( _In_ int af, _In_ int type, _In_ int
范蠡
2018/04/04
4.6K0
如何将MySQL GR 设置为多主模式
在MySQL 5.7.17版本中发布的MySQL Group Replication(后文简称为MGR)被很多人称为MySQL复制方案的正规军,可以一举取代现在的MySQL Replication,Semisynchronous replication,甚至是可以取代之前最成功的MySQL集群方案Galera。 MGR有两种模式,一种是Single-Primary,一种是Multi-Primary,单主或者多主。 在前一种模式Single-Primary中,无论集群中有多少个节点,只有一个节点允许写入,其它
数据和云
2018/03/07
3.9K0
如何将MySQL GR 设置为多主模式
升级为Rust,Hive勒索软件加密将变得更加复杂
近期,微软安全部门的研究人员发现了一种名为Hive的升级版勒索软件服务(RaaS),随即安全专家在周二的一份报告中概述了他们的发现,在报告中,专家们阐述了以下观点:随着其最新版本的几个重大升级,Hive也证明了它是发展最快的勒索软件家族之一,也例证了不断变化的勒索软件生态系统。 根据微软的说法,Hive勒索软件最新版本的升级代表着对整个勒索软件基础架构的彻底改革,在报告中,专家们还指出最值得注意的变化,包括将完整的代码迁移到另一种编程语言(从GoLang迁移到Rust),以及使用更复杂的加密方法。 Hive
FB客服
2023/03/30
3270
升级为Rust,Hive勒索软件加密将变得更加复杂
次世代的会话管理项目 Spring Session
原文作者:Adib Saikali 原文地址:https://www.infoq.com/articles/Next-Generation-Session-Management-with-Spring
Techeek
2018/06/25
1K0
点击加载更多

相似问题

将正常项目升级为Xamarin.Forms项目

11

数独项目无法为按钮分配级别

10

单元测试数独-测试应该尝试独立于数独板的数据结构吗?

16

将旧go项目升级为使用go模块

13

会话项目始终为空

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文