游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4655|回复: 11

问个Gimbal Lock的问题

[复制链接]

30

主题

146

帖子

152

积分

注册会员

Rank: 2

积分
152
发表于 2008-4-15 21:20:00 | 显示全部楼层 |阅读模式
我理解的Gimbal Lock是这样的
三维空间有x,y,z三个轴,一个物体有x',y',z'三个朝向
现在假如x'与x平行,那么当物体绕y旋转90度时,x'会旋转到与z平行的方向
此时,物体绕z旋转是改变不了x'方向的。
我看很多地方说丢失1维,或者坐标轴重合,说的是不是这里的丢失z这1维,或者x'和z重合啊?

但是,觉得很奇怪,朝向和轴平行,绕轴旋转当然是改变不了朝向的(只能改变另外两个朝向)。
那Gimbal Lock的问题,难道是说多次旋转中的某一阶段发生Gimbal Lock现象,导致旋转不下去?

36

主题

1047

帖子

1147

积分

金牌会员

Rank: 6Rank: 6

积分
1147
发表于 2008-4-16 00:07:00 | 显示全部楼层

Re:问个Gimbal Lock的问题

你把头仰到最后,每个轴转一下试试就知道了.

30

主题

146

帖子

152

积分

注册会员

Rank: 2

积分
152
 楼主| 发表于 2008-4-16 12:33:00 | 显示全部楼层

Re:问个Gimbal Lock的问题

别发这种无聊的回复。

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
发表于 2008-4-16 13:56:00 | 显示全部楼层

Re:问个Gimbal Lock的问题

我最近也在研究四元数和欧拉角,这东西还是有那么点复杂的。
欧拉角主要是存在旋转顺序的问题,导致很多不确定因素。
旋转矩阵是三轴旋转以后的结果,如果只是结果
所以无法知道物体确切来说究竟是怎么旋转到当前的状态的。
所以欧拉角如果没有一个固定旋转姿态,是无法知道怎么旋转过来的,正是这种不确定因素导致了万象节锁的产生

而四元素则不同,如果所绕的轴变化了,这其中做插值计算是平滑的,旋转姿态永远都是确定的
所以连续运动中的旋转对象,用四元素插值计算再推矩阵是最恰当的
但四元素也不是没有问题的,首先,人机交互根本没办法输入四元素,那样太抽象了

我最近就是做人机交互,还要把四元数或旋转矩阵换算成zxy姿态的欧拉角,不过还好就在今天早上,算是搞定了了。

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2008-4-16 17:57:00 | 显示全部楼层

Re:问个Gimbal Lock的问题

看看你家的电视机天线。或收音机天线。

x,y的旋转模式是不同的。

x轴是天线自己的x轴(可变)

y轴永远是世界的y轴(固定)

当天线竖起来之后,就转不动了。

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2008-4-16 17:58:00 | 显示全部楼层

Re:问个Gimbal Lock的问题

以前翻译一个日文的时候,曾经把它翻译成
吉恩瓦尔洛克 orz

后来知道Ginbal Lock是万向节锁。

30

主题

146

帖子

152

积分

注册会员

Rank: 2

积分
152
 楼主| 发表于 2008-4-16 20:30:00 | 显示全部楼层

Re:问个Gimbal Lock的问题

结合tonykee和instemast说的,
由于不确定的因素,导致欧拉旋转的某个阶段产生物体自身坐标轴和世界坐标轴平行的现象,此时产生万向节锁现象,无法旋转下去了。但由于不确定的因素,如果换个欧拉旋转顺序可能就不会发生万向节锁现象了。
是这样的吧?

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
发表于 2008-4-16 20:57:00 | 显示全部楼层

Re:问个Gimbal Lock的问题

差不多吧,当转轴平行于世界轴的时候,讨厌的死锁就发生了

另外更重要的是:欧拉角不能表示连续变化的旋转,如果规定一定是先转什么轴再转什么轴,那当然是可以,可无法模拟真实连续的旋转。事实上真实连续的旋转,先绕那个轴,再绕那个轴是不固定的。

当然姿态固定的情况下,欧拉角当然是可以,姿态连续变化欧拉角就不太合适了。不过据说也有人用限制欧拉角的范围来解决这个问题,但还是不够理想。连续变化的差值的旋转,四元数才是最合适的方法。

总体上说:转轴不变化,一定姿态的欧拉角来描述是可以,转轴不断变化的情况还是四元数比较合适

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
发表于 2008-4-16 21:07:00 | 显示全部楼层

Re:问个Gimbal Lock的问题

Gimbal Lock


。。。
Maybe it's a bit difficult to understand. OK, let me show you a real sence.

可能有点不好理解。让我们看个现实中的场景。

Say that we have a telescope and a tripod to put the telescope on. The tripod is put on the ground. The top of the tripod holding the telescope is leveled with the horizon (reference plane) so that a vertical rotation axis (we call it X axis) is perfectly vertical to the ground plane. The telescope can then be rotated around 360 degrees in X axis so that it can scan the horizon in all the directions of the compass. Zero degrees azimuth is usually set toward a heading of true north. A second horizontal axis parallel to the ground plane (we call it Y axis), enables the telescope to be rotated in elevation upward or downward from the horizon. The horizon is usually set at zero degrees and the telescope can be rotated +90 degrees upward in elevation so that it is looking straight up toward the zenith or rotated -90 degrees downward so that it is looking vertically at the ground plane.

假如我们有一个望远镜和一个用来放望远镜的三脚架,(我们将)三脚架放在地面上,使支撑望远镜的三脚架的顶部是平行于地平面(参考平面)的,以便使得竖向的旋转轴(记为x轴)是完全地垂直于地平面的。现在,我们就可以将望远镜饶x轴旋转360度,从而观察(以望远镜为中心的)水平包围圈的所有方向。通常将正北朝向方位角度记为0度方位角。第二个坐标轴,即平行于地平面的横向的坐标轴(记为y轴)使得望远镜可以饶着它上下旋转,通常将地平面朝向的仰角记为0度,这样,望远镜可以向上仰+90度指向天顶,或者向下-90度指向脚底。

OK, that's all we needed. every point in the sky (and the ground) can be referenced by only ONE unique pair of X and Y readings. For example an X of 90 degrees and Y of 45 degrees specifies a point exactly due east of the telescope and in a skyward direction half way up toward the zenith.

好了,万事俱备。现在,天空中(包括地面上)的每个点只需要唯一的一对x和y度数就可以确定。比如x=90度,y=45度指向的点是位于正东方向的半天空上。

Now let me show you how the gimal lock occurred. We detect a high flying aircraft, near the horizon, due east from the telescope (X = 90 degrees, Y = 10 degrees) and we follow it (track it) as it comes directly toward us. The X angle stays at 90 degrees and the Y angle slowly increases. As the aircraft comes closer the Y angle increases more rapidly and just as the aircraft reaches an Y of 90 degrees (exactly overhead), it makes a sharp turn due south. We find that we cannot quickly move the telescope toward the south because the Y angle is exactly +90 degrees so we loose sight (loose track) of the aircraft . We have GIMBAL LOCK!

现在,看看万向节死锁是怎么发生的。一次,我们探测到有一个飞行器贴地飞行,位于望远镜的正东方向(x=90度,y=10度),朝着我们直飞过来,我们跟踪它。飞行器飞行方向是保持x轴角度90度不变,而y向的角度在慢慢增大。随着飞行器的临近,y轴角增长的越来越快且当y向的角度达到90度时(即将超越),突然它急转弯朝南飞去。这时,我们发现我们不能将望远镜朝向南方,因为此时y向已经是90度,造成我们失去跟踪目标。这就是万向节死锁!

(译注:为什么说不能将望远镜朝向南方呢,让我们看看坐标变化,从开始的(x=90度,y=10度)到(x=90度,y=90度),这个过程没有问题,望远镜慢慢转动跟踪飞行器。当飞行器到达(x=90度,y=90度)后,坐标突然变成(x=180度,y=90度)(因为朝南),x由90突变成180度,所以望远镜需要饶垂直轴向x轴旋转180-90=90度以便追上飞行器,但此时,望远镜已经是平行于x轴,我们知道饶平行于自身的中轴线的的旋转改变不了朝向,就象拧螺丝一样,螺丝头的指向不变。所以望远镜的指向还是天顶。而后由于飞行器飞远,坐标变成(x=180度,y<90度)时,y向角减小,望远镜只能又转回到正东指向,望'器'兴叹。这说明用x,y旋转角(又称欧拉角)来定向物体有时并不能按照你想像的那样工作,象上面的例子中从(x=90度,y=10度)到(x=90度,y=90度),按照欧拉角旋转确实可以正确地定向,但从(x=90度,y=90度)到(x=180度,y=90度),再到(x=180度,y<90度),按照欧拉角旋转后的定向并非正确。)

It's a example of 2D coordinate frame. It's very similar in 3D frame. We say that you have a vector which is parellel to the X axis. And we rotate it around  Y axis so that the vector is parellel to the Z axis. Then we find that any rotations around  Z axis will have no effect on the vector. We say that we have a GIMBAL LOCK

上面是2维坐标系中的例子,同样,对于3维的也一样。比如有一个平行于x轴的向量,我们先将它饶y旋转直到它平行于z轴,这时,我们会发现任何饶z的旋转都改变不了向量的方向,即万向节死锁。


362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2008-4-17 00:08:00 | 显示全部楼层

Re:问个Gimbal Lock的问题

CS里面的旋转,你可以体会一下,是这样的:
<和天线一样,天线的旋转机构就叫做"Ginbal">

左右旋转,是绕着世界的 y 轴进行的,(竖直向上的轴)
抬头低头,是绕着自己的 x 轴进行的,(你身体左侧方向的轴)

当头抬到顶的时候,你自己的 z 轴(视线方向)和世界的 y 轴重合(竖直向上了),
(你自己的 y 轴,即头顶方向将会变成地平线)

这时候你自己的 z 轴(视线方向)便不会旋转,视野里天花板上的灯的位置也不会移动。

因为人的左右旋转,是躯干的旋转(躯干是竖直的),而上下旋转,是头部的旋转。

在CS中,你从未看见过一个倾斜的大楼!
这是因为:
1 没有倾斜旋转操作(倾斜头部)
2 左右旋转总是围绕竖直方向,那么你自己的 x 轴将总是水平的,具体是因为:

你的 x 轴(身体左侧方向)初始是水平的,旋转过程中只有2种情况:
(1)左右移动鼠标: 你的 x 轴可以绕 铅直线旋转,当然还是水平的。
(2)上下移动鼠标: 你的 y,z 轴围绕你的 x 轴旋转,所以 x 轴自己就不转。


写这个帖子把我写的快要晕了。。。

总的来说,我用3个坐标轴来控制旋转,这样不会有问题,
其中一个轴不转了,其他的轴会转。


看一下我的摄像机的位置控制:
        case 'L':
                pcamera->RotateByParent(0,RotateSpeed,0);
                break;
        case 'J':
                pcamera->RotateByParent(0,-RotateSpeed,0);
                break;
        case 'I':
                pcamera->RotateByLocal(-RotateSpeed,0,0);
                break;
        case 'K':
                pcamera->RotateByLocal(RotateSpeed,0,0);
                break;
// 从父母空间到本地空间的矩阵。(这里,世界是摄像机的父母)
g_pg->SetTransform(TS_VIEW,pcamera->GetMat44FromParent());


我的 CPosCtrl 类里面通过维护3个本地坐标轴在父母空间中的坐标值,来进行位置控制:
        void MoveByParent(Float dx,Float dy,Float dz);
        void MoveByLocal(Float dx,Float dy,Float dz);
        void SetPosByParent(const VEC3 *pos);
        void SetPosByParent(Float x,Float y,Float z);
        const VEC3 *GetPosByParent()const;
        void GetPosByParent(Float *x,Float *y,Float *z)const;
        void RotateByLocal(Float x,Float y,Float z);
        void RotateByParent(Float x,Float y,Float z);
        MAT44 GetMat44ToParent()const;
        MAT44 GetMat44FromParent()const;
        VEC3 m_Pos; // by parent coord
        VEC3 m_Look; // z axis ,by parent coord
        VEC3 m_Up; // y axis ,by parent coord
        VEC3 m_Right; // x axis ,by parent coord
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-5-18 14:17

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表