欢迎光临ELBE网站!
您的位置: ELBE > 行业资讯 > 三维快速旋转与发动机锁等待
网站头像

文章分类

Article classification
联系我们

ELBE

电话:021-58780503 微信:18017854633 邮箱:sales_fullyear@126.com 地址:上海市浦东新区城南路168弄3号峰汇商务广场B座911室
三维快速旋转与发动机锁等待
时间:2023-04-09 查看:27 作者:小叶

由上,我们可以发现,一个三维旋转可以用一个旋转平面、一个不动点、一个旋转方向、一个旋转角来定义,如果称旋转前的点为“原始点”,则旋转可定义为:在旋转平面上,以不动点为圆心,以不动点到原始点的距离为半径做一个圆,在该圆上以原始点为起点往旋转方向画一道弧,该弧对应的角度大小等于旋转角,则该弧的中点为旋转后的点。

旋转的代数表示

我们已经知道一个旋转在几何上可以用一个旋转平面、一个不动点、一个旋转方向、一个旋转角来定义,但是计算机要表示旋转的话,需要更加代数化的表示,最好就是向量、矩阵这类数的排列。我们一个个来看:

旋转平面也只是一个普通的平面而已,而任何一个平面都能用平面上的一点和垂直于该平面的法向量来定义。我们知道原始点和不动点必定在旋转平面上,所以要表示一个旋转平面用一个向量就够了。不动点,就是对应的坐标数值构成的一个向量而已。旋转方向,我们可以定义与上文中提到的旋转平面的法向量满足右手螺旋法则的方向为旋转方向。右手螺旋法则就是说,举起右手,把大拇指立起来,让大拇指朝向法向量方向,最后把剩下四指收进掌心,则此时四指的方向就是旋转方向。旋转角,就只是一个实数来表示大小而已。

综上,一个旋转要用代数来表示的话需要四样东西:一个表示旋转平面法线方向的向量,一个表示不动点的向量,一种由旋转平面法向量得出旋转方向的规定,一个表示旋转角度的实数。

假如我们规定不动点是原点,并使用右手螺旋法则来求旋转方向,且称旋转平面法向量为“旋转轴”,那么一个旋转就只有两样东西:旋转轴、旋转角——一个向量、一个实数。之后我们说“旋转”的时候都是指这样一个只由旋转轴、旋转角表示的旋转。

旋转的运算

上文中最后指出一个旋转可以只由旋转轴和旋转角来表示,这样它确实很容易被计算机存储,但我们的最终目标是快速地计算出旋转后的点的坐标。所以不止是存储,我们还需要一套方便的运算方法。

注:一般来说,旋转的运算有两类方法,矩阵运算与四元数运算。这里只提及矩阵运算的思想,因为四元数的话,必须讲解数学,比较麻烦,而且使用恰当时,四元数也不会带来万向节死锁问题。

计算机中计算旋转,是通过叠加的方式来实现的。首先,应该很容易明白,如果先做一个旋转,再做另一个旋转,那么实际上这两个旋转叠加的效果相当于做了一个等效的旋转,也就是两个旋转叠加以后还是一个旋转。这是因为根据旋转的定义,两次旋转都不会改变点到不动点的距离。具体来说,如果原始点是x,第一次旋转后变成了x1,第二次旋转后是x2,那么x, x1, x2到不动点的距离是相等的,所以我们可以把x到x2的这一整个过程看作是一个单独的旋转。

其次,还应该能比较容易地接受一个结论:绕任意旋转轴的旋转都可以由三个分别绕x,y,z轴的旋转叠加得到。也就是,若C是一个任意旋转,则总是存在绕x轴的旋转X,绕y轴的旋转Y,绕z轴的旋转Z,使得C(p)=Z(Y(X(p)))。关于这一结论,此处不作展开。通过应用这一结论,计算机内部可以用三个旋转的叠加来表示任意旋转。而绕x, y, z轴的旋转后的点都是比较容易得到的。

以绕z轴的旋转角为θ的旋转为例,若旋转前的点的坐标为

,旋转后的坐标为

,则有

,若用矩阵、向量的形式来写的话,就是

。关于x, y轴的旋转也都可以如此用矩阵运算来表示。

而矩阵之间可以用乘法进行运算得到一个新矩阵,所以如果绕z,y,x轴的旋转矩阵分别为Z,Y,X,那么它们的乘积ZYX也是一个旋转矩阵。

万向节死锁

由上文可知,我们总是可以用三个分别表示绕x,y,z轴旋转的矩阵的乘积来表示任意一个旋转运算。这看起来似乎没有问题,事实上,绝大多数情况也确实没有任何问题。

这里要稍微偏离一下话题,考虑一下自己的手臂。观察手臂的构造,我们可以发现它大致为:肩膀-肩关节-上臂-肘关节-小臂-腕关节-手。也就是我们用三个关节连接了四块部件,这三个关节为我们的手臂提供了灵活性,因为我们的骨头可以在关节处旋转。如果没有关节的话,手臂就会是笔直笔直的,没法弯曲了。来做一个不符合实际的假设,假设肩关节只能沿z轴旋转(把你的上臂上下抬动),肘关节只能绕y轴旋转(缩起小臂到胸前这类的),腕关节只能绕x轴旋转(让你的拳头像拨浪鼓一样转来转去),然后把手摊开,考虑手心的面向与手指的朝向。如果我们的关节能360度旋转的话,那这就和上面提到的三个沿坐标轴的旋转的叠加是一样的。转动肩关节时,显然我们的掌心也会跟着转动,改变面向,这说明肘关节的转动作用到了手的转动这边。显然,肘关节、腕关节的转动也会作用到手上,也就是说三个关节的转动叠加到了手上面。另一方面,因为上面提到任意旋转都能由三个沿坐标轴的旋转的叠加得到,所以我们的手心和手指能朝向任何方向。这看起来没有问题。

但是此时考虑一种情况,如图中所示(模型使用 ** gic poser web),抬平上臂,把小臂抬平到胸前。然后尝试腕关节的旋转和肩关节的旋转,我们会发现,这两个不同的关节的旋转,会使得手心朝向的转变是相同的——都是沿z轴,也就是肩关节绕着旋转的那个轴,而手指的朝向则是固定不变的。换句话说,我们本应是分别沿x轴、z轴这两个方向的旋转,现在变成了沿相同方向的旋转了。

为什么会这样呢?注意到三个关节并不是独立的:肩关节的旋转会带动肘关节和腕关节的移动,肘关节的旋转也会带动腕关节的移动。正如同这三个关节都会作用到位处手臂末端的手一样,上面的关节也会作用到下面的关节。旋转肩关节时会同时带动肘关节和腕关节,所以对之后肘关节与腕关节的旋转产生的影响是相同的。但是肘关节只会带动腕关节,不会带动肩关节。上文中,抬平小臂到胸前的行为就转动了肘关节,从而影响到了腕关节,但是没有对肩关节产生影响,结果导致腕关节旋转的效果变成与肩关节旋转一样的效果了。

回到原来的问题,在计算机中用三个矩阵表示任意旋转是否也会有同样的问题呢?注意到上述问题之所以会产生是因为中间的关节会影响到最下面的关节,而不会影响到最上面的关节。再看看矩阵表示的旋转,我们用ZYX这一矩阵乘积来表示任意旋转,也就是p'=ZYXp,我们将Z,Y,X,ZYX这四个矩阵都给写出来看看:

若我们取

,则乘积变为

,注意到无论我们怎样修改θ、φ,都不会改变z’的值,z’始终等于-x。也就是说,当我们沿y轴旋转90°时,此时X,Z这两个旋转矩阵都是在进行绕z轴的旋转。这与之前手臂的情况是相同的。因为矩阵的相乘作用到p点也是有顺序的,我们先左乘X,再左乘Y,那么在乘Y时,实际上也影响到了已经乘进去的X。而在乘Z的时候,会对X和Y产生相同的影响。所以这里的p就相当于我们的手心与手指的朝向,X相当于腕关节,Y相当于肘关节,Z相当于肩关节。Y会对X产生影响,但影响不到Z,使得X变成与Z沿着相同轴旋转的矩阵。

结语

本文讲了讲旋转的定义、计算机中旋转的运算方式,然后重点讲解了随之而来的万向节死锁问题。在这里顺带提一下万向节这东西,原版的万向节中之所以会有万向节死锁问题,也是因为三个环并不完全独立,中间的环会带动最里面的环,但不会影响到最外面的环。万向节死锁问题是个不可避免的问题,只要使用不相互独立的三次旋转来表示任意旋转,都会带来这一问题。但是万向节死锁并不可怕,它仅仅只会在中间的旋转取极端值的情况下出现,若我们只是想表示一个旋转,那万向节死锁不会带来任何问题,毕竟我们总是能找到沿坐标轴的三个旋转来表示任意旋转。万向节死锁只会在需要旋转不断叠加的情况下才会导致问题,例如飞机控制、旋转插值。所以在那方面的应用中,本文没有提及的四元数被广泛引用。

万向节死锁到底是什么,它又为何产生这问题实在是困扰了我相当久,仅以此 ** 个记录,若有不正之处,欢迎指出。

继续阅读与本文标签相同的文章
cache
Processed in 0.014011 Second.