万向锁问题详解,以Unity为例

article/2025/7/21 0:17:11

转载自:https://blog.csdn.net/fengya1/article/details/50721768

 

根据上面的说明两个旋转面(圆圈)怎么会共面,让我迷糊。假设共面,那这两个旋转面的法线应该是旋转轴,要想两个面共面,那旋转轴肯定平行的。但问题是以模型坐标(齐次坐标系)为旋转轴,无论旋转那个轴,其它两个轴也会相应的变化,而且相互垂直。就不会发生共面,不会出现万象锁???

网上说欧拉角坐标轴旋转是按顺序旋转的,即父子关系,如下图

还是不明白上图的旋转轴在哪???!

下面我用unity演示一下

从上面看,无论旋转那个轴,旋转后,他们的旋转轴都是垂直的。假设绕x轴旋转,y轴和z轴所确立的面就是这个变换的旋转面。问题来了,既然无论怎么旋转,旋转轴都是垂直的,当你旋转是其他轴所确立的旋转面也会旋转,保持垂直关系。那怎么会出现两个旋转面共面呢??

下面开始说明万象锁(以unity 3D 说明)

先说明unity 3D欧拉角的旋转顺序(父子关系)是y-x-z。即旋转y轴x和z轴都变,旋转x轴只有z轴变化,旋转z轴其它轴不变。

再解释说明前,先说明一些坐标概念。

模型坐标系---及模型导入时的坐标系,通过此坐标系记录模型顶点等的位置。

世界坐标系---主要作用是表示模型与模型间的相对位置。

惯性坐标系---和模型坐标系原点相同,但是坐标轴的方向和世界坐标系相同,作用应该是模型到世界变换的桥梁吧。

具体请参照图书《3D数学基础:图形与游戏开发》

引入惯性坐标是为了便于说明(实事上旋转是在一个坐标系上进行的)(在总结的时候会加以说明)

unity模型坐标系和惯性坐标系间的查看方法

local为模型坐标系

global为惯性坐标系

如果你不旋转模型,此时惯性坐标系和模型坐标系重合,你可以点选上面按钮切换看一下。

ok,为了方便说明,我们用辅助线将惯性坐标系画到模型上,坐标轴颜色和模型坐标轴相对应

代码如下:

先创建一个脚本,名称为tuxingfuzhu.cs脚本,

代码: 

using UnityEngine;
using System.Collections;
//using UnityEditor;
public class tuxingfuzhu : MonoBehaviour {
    public Mesh mesh;
// Use this for initialization
void Start () {

}
    /// <summary>
    /// 如果你想绘制可被点选的gizmos,执行这个函数
    /// </summary>
    void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Vector3 direction = Vector3.right* 2;  //世界坐标系的 轴向x
        Gizmos.DrawRay(transform.position, direction);
        Gizmos.color = Color.green;
         direction = Vector3.up* 2;   //世界坐标系的 轴向y
        Gizmos.DrawRay(transform.position, direction);
        Gizmos.color = Color.blue;
         direction = Vector3.forward* 2;     //世界坐标系的 轴向z
        Gizmos.DrawRay(transform.position, direction);


    
    }


    /// <summary>
    /// 如果你想在物体被选中时绘制gizmos,执行这个函数
    /// </summary>
    void OnDrawGizmosSelected()
    {


        //Gizmos.color = Color.white;
        //Gizmos.DrawSphere(transform.position, 1);


    
    }
// Update is called once per frame
void Update () {

}
}

代码说明

Gizmos.DrawRay   //绘制辅助射线,有关辅助工具请查阅unity官网的Gizmos类。

然后将脚本挂载到要测试的物体上,这里我挂在到了cube物体上,效果如下:

我们看到模型多了三条长线(惯性坐标)。

ok,现在进行旋转说明。

首先将坐标切换到模型坐标,

下面将模型x和z轴分别旋转45度。

点选你的测试模型,效果如下图

ok,现在模型坐标和惯性坐标分离了。

好,现在我们开始旋转最顶层的y轴。

效果如下图:

你发现了什么???

你会发现旋转y轴是绕着惯性左边的y轴旋转的,而不是模型的坐标。

ok,现在将z轴置0,然后旋转x轴,y轴可以有一定的度数,为了作对照。

效果如下图:

此时你会发现x轴的变换是绕着模型坐标的x轴进行变换的。

ok,接着进行z轴的变换,如下图:

你会发现z轴的变换也是绕着模型的z轴变换。

到这里问题就差不多了。为什么会共面,因为y轴变换将影响x和z轴,因为有轴处在变换的最顶层(y-x-z),最主要的是y轴变换是模型在惯性坐标里变换,而其他轴的变换是在模型轴变换。所以就会出旋转面共面(万向锁)的情况

下面开始说明万向锁的情况。

将模型x轴旋转90度(或者-90度)(最简单的万向锁)

紧接着旋转y轴或者z轴,效果如下:

这就是万向锁

你会发现z轴旋转和y轴旋转效果是一样的,同时你会发现z轴(模型坐标系)和y轴坐标(惯性坐标系)平行。

此时y轴(惯性坐标系)旋转面和z轴(模型坐标系)旋转面共面如下图,

从上图很容易看出旋转y轴(惯性坐标系)和旋转z轴(模型坐标系)是一样的效果,只不过方向相反或相同。

让我困惑的问题解决了。

总结:

万向锁产生时两个旋转轴平行(旋转面共面)是模型的旋转失去的一个方向的旋转。

最主要的是弄明白旋转是围绕着什么样的坐标系做旋转。

上面的解释只是从表面上解释了万向锁

实际上模型的旋转是以一个坐标系进行旋转。但上面解释是等效的。下面解释一下。

计算机模型的旋转过程不是我们想的连续旋转。什么意思呢?

假设U3D每一帧绕Y旋转5度,他的旋转过程是:第一次旋转从(0,0,0)绕Y轴旋转5度为(0,5,0),到现在还没有问题,那第二次旋转会是什么情况呢。

有人说,简单,再从现在以变换的模型旋转(0,5,0)绕Y轴旋转5度---->(0,10,0)不就行了。但计算机不会这样做。它是在原模型坐标(0,0,0)重新开始变化,

即(0,0,0)------>(0,10,0)。

就是说模型的变换都是(0,0,0)开始变换,主意,知道这一点才是最主要的。

当模型绕Y-X-Z顺序旋转时,当模型发生旋转变换时:

步骤1.每次变换的顺序都是(0,0,0)-------------->(x,y,z),即都是从(0,0,0)开始,先变换Y轴,在变换X轴,然后在变换轴。

每次只要有变换,都要重复步骤1的过程。

每次旋转都先绕Y轴旋转,所以每次旋转变换的Y轴方向是不变的,和惯性坐标重合。所以我上面的旋转是以惯性坐标去解释。其实这个困惑是时间上的先后顺序产生的,准确的

说是时间上的共轴或共面

下面我演示变换过程如下图:

上面演示了三次图形变换(0,0,0)----->(58,67,40);  (0,0,0)-------->(45,87,60);   (0,0,0)-------->(45,67,67)

在变换时,内部程序都是从(0,0,0)开始变换(算法)的。即使你再U3D参数设置上可以在现有的变换进行变换,但程序内部还是从(0,0,0)开始变换。

从上面三次(或者更多次)变换,你会发现三次变换的第一次Y轴变换的轴是一样的。绿色的圆为旋转面。

接下来是X轴旋转,z轴旋转。即使Y轴变换了,但是三次变化在第一次绕y轴变换的时刻Y轴是不变的。所以y轴与Z轴会有共线,或者说Y轴的旋转轴和Z轴的旋转轴共面只

是在时间变换上的共面。(万向锁的产生)

在U3D中,旋转顺序是y-x-z(模型坐标---惯性坐标系旋转),官网为z-x-y(惯性坐标系----模型坐标)。

y轴是惯性坐标系的y轴,其它轴是模型的坐标轴。这是因为不同坐标系的轴才有可能产生共面

如果不明白坐标系的,具体请查阅《3D数学基础:图形与游戏开发》图书。

打个广告吧。推荐一下吧,非常基础,非常形象易懂的图形学图书。

万象锁有关视频

http://v.youku.com/v_show/id_XNzkyOTIyMTI=.html
 


http://chatgpt.dhexx.cn/article/R4UcaF8b.shtml

相关文章

UE4解决万向锁问题

万向锁 目录万向锁的来源Unity中最简单的万向锁UE4最简单万向锁解决方案四元数与欧拉角之间的转换参考链接 目录 万向锁的来源 简单而言&#xff0c;万向锁就是由于物体在进行旋转时&#xff08;前提是通过欧拉角进行旋转&#xff09;&#xff0c;当旋转到某个特定角度会导致…

万向锁(Gimbal lock)问题的理解及解决

万向锁(Gimbal lock)问题的理解及解决 万向锁&#xff08;Gimbal lock&#xff09;&#xff1a; 一旦选择90作为pitch角&#xff0c;就会导致第一次旋转和第三次旋转等价&#xff0c;整个旋转表示系统被限制在只能绕竖直轴旋转&#xff0c;丢失了一个表示维度。 对于万向锁的…

欧拉角表示旋转会出现的问题——万向锁(Gimbal Lock)

本文用来总结万向锁问题。尽量写得非常简单&#xff0c;方便自己复习和后人理解&#xff0c;水平有限若有错误请指教。 一、旋转的表示 本文中矩阵计算的结果是在世界坐标系&#xff08;称之为North East Down Frame NED Frame)中的坐标&#xff1b; 参考文章中最后矩阵计算的…

旋转矩阵、欧拉角,万向锁的危害

1. 万向锁会带来什么危害&#xff1f; 最近看了很多万向锁的文章&#xff0c;大家都集中于讲述万向锁的成因&#xff0c;最后都会加上句“导致缺失一个方向的自由度”&#xff0c;但是万向锁现象到底会给实际工作带来什么问题&#xff1f;具体点&#xff0c;万向锁会给姿态解算…

资料分享:一文搞懂万向锁

大家好&#xff0c;我是被深圳台风吹飞的小鱼。台风老哥太暴躁&#xff0c;早上上班裤子都湿了 今天给大家分享一篇文章&#xff0c;主要讲的是欧拉角的万向锁现象&#xff0c;大家知道表示旋转的方式有很多&#xff0c;其中欧拉角就属于比较常见的一种方式&#xff0c;但是欧…

【SLAM学习笔记1】欧拉角之万向锁问题(Gimbal Lock)

文章目录 前言一、欧拉角1.欧拉角是什么&#xff1f;2.使用欧拉角的优缺点 二、万向锁问题的预备知识1.Gimbal&#xff08;平衡架&#xff09;2.相关术语 三、万向锁问题1.Gimbal Lock&#xff08;万向锁问题&#xff09;的现象2.Gimbal Lock&#xff08;万向锁问题&#xff09…

[视觉SLAM十四讲]学习笔记2-关于欧拉角和万向锁

[视觉SLAM十四讲]学习笔记2-关于欧拉角和万向锁 1 欧拉角1.1 维基百科定义1.2 ZYX欧拉角与rpy角 2 万向锁2.1 万向节2.1 万向锁的产生 1 欧拉角 1.1 维基百科定义 关于欧拉角的定义&#xff0c;维基百科中这样给出&#xff1a;莱昂哈德欧拉提出用欧拉角来描述刚体在三维欧几里…

Unity 旋转欧拉角及万向锁问题

先说明unity 3D欧拉角的旋转顺序&#xff08;父子关系&#xff09;是y-x-z。即旋转y轴x和z轴都变&#xff0c;旋转x轴只有z轴变化&#xff0c;旋转z轴其它轴不变。 模型坐标系 又称物体坐标系。 与特定的物体关联&#xff0c;每个物体都有自己特定的坐标系。不同物体之间的坐…

万向锁的理解 欧拉角 四元数

1 欧拉角&万向锁 欧拉角和万向锁 视频资料理解万向锁 核心是嵌套 以一个三自由度的机械臂为例&#xff0c;三个旋转轴互相垂直&#xff0c;相当于x,y,z轴 三个机械臂通过旋转关节依次串联&#xff0c;定义第一个关节旋转轴为J1&#xff0c;以此类推第二第三个关节旋转轴为…

简单研究Unity中的万向锁和欧拉角以及四元数

欧拉角是欧拉在17世纪发明引进的一个数学工具&#xff0c;在三维欧几里得空间内&#xff0c;欧拉角可以确定一个物体的朝向。在解决静态问题上&#xff0c;欧拉角是一个比较完美的解决方案&#xff0c;但在动态问题上&#xff0c;欧拉角有一个万向锁的瑕疵&#xff0c;数学界在…

Unity万向锁

结论&#xff1a; 当第二轴旋转90时会产生万向锁&#xff0c;万向锁只发生在程序中&#xff0c;现实世界不会发生。 发生万向锁的底层原因是由于程序中会指定旋转顺序&#xff0c;且前后顺序为父子包含关系。 旋转顺序&#xff1a;因为同样一组数据&#xff0c;例如{X:10&…

欧拉角与万向锁—深度解读万向锁

文章目录 问题描述&#xff1a;Z轴不生效&#xff08;轴向重合&#xff09;轴向为什么会重合初态二次变换总结&#xff1a;解决办法&#xff1a; 相信很多人听说过欧拉角与万向锁&#xff0c;主要问题是欧拉角为什么会产生万向锁&#xff1f; 有矩阵解读法&#xff0c;但是不够…

关于万向锁(Gimbal lock)问题的理解及解决

有时间更新一下理解&#xff0c;现在回过头来看写的东西真是垃圾哈哈哈哈哈~~~~ 1. Gimbal lock的理解 万向锁&#xff08;Gimbal lock&#xff09;&#xff1a; 一旦选择90作为pitch角&#xff0c;就会导致第一次旋转和第三次旋转等价&#xff0c;整个旋转表示系统被限制在只…

详解万向锁

最近在看高翔老师的slam十四讲时&#xff0c;对万向锁这个概念不是很清晰&#xff0c;于是从网上查了不少博客文档&#xff0c;最终明白了万向锁这个概念。 在此记录一下。 解释万向锁之前首先明白一下什么是欧拉角。 什么是欧拉角&#xff1f; 用一句话说&#xff0c;欧拉角…

java uuid多少位_UUID用在MySQL中,性能到底好不好?

如果你在网上快速的做一个关于 UUID 和 MySQL 的搜索&#xff0c;你会得到相当多的结果。以下是一些例子&#xff1a; 存储 UUID 和 生成列在 MySQL 中存储 UUID 的值说明 InnoDB 中的主键模型及其对磁盘使用的影响主键选型之战 UUID vs. INTGUID / UUID 的性能突破到底需不需要…

UUID 全世界的唯一id!(唯一的接口标识符)

UUID(Universally Unique IDentifier)是一个128位数字的唯一标识。RFC 4122描述了具体的规范实现。本文尝试从它的结构一步步分析为什么它能做到唯一性&#xff1f;及各个版本的使用场景。 Format UUID使用16进制表示&#xff0c;共有36个字符(32个字母数字4个连接符"-&…

瓦片地图加载

OpenLayers之加载多源数据四&#xff1a;万能瓦片地图加载秘籍 不睡觉的怪叔叔 2018-08-02 13:46:59 7175 收藏 17 分类专栏&#xff1a; 开源GIS 目录 加载简单的瓦片地图 瓦片地图之高德地图 瓦片地图之百度地图 重新定义OpenLayers3的瓦片坐标系 分析瓦片地图坐标系…

QGIS 上加载瓦片地图(高德、ESRI、OSM等)

1. 在QGIS左侧的浏览面板中&#xff0c;选择XYZ Tiles节点&#xff0c;右键新建连接。在弹出的窗口中填入名称和瓦片地图的网址http://webrd02.is.autonavi.com/appmaptile?langzh_cn&size1&scale1&style7&x{x}&y{y}&z{z} &#xff0c;保存。 2.将浏览…

QGIS二次开发:加载XYZ Tiles形式的瓦片地图

1.前言 QGIS官方提供的QGIS.exe可以加载远程地图提供商提供的基于URL格式的XYZ Tiles形式的瓦片地图。如:https://tile.openstreetmap.org/{z}/{x}/{y}.png ,开发者如果不能联网,也可以创建离线地图服务。如下:打开QGIS 3.26.2.exe,选择xyz Tiles节点,单击右键,选择“N…

Vue Mapbox 发布高德瓦片地图

一、需求来源 公司网站开发需求里需要做一个大屏看板&#xff0c;包含地图的功能&#xff0c;而且以后是要在内网使用的&#xff0c;也就是说不能使用在线网络。我在研究了&#xff08;踩了一万个坑&#xff01;&#xff01;&#xff01;&#xff09;多个地图组件以后&#xff…