如何计算n维空间中的旋转矩阵,给定旋转点、旋转角度和旋转轴(n-2子空间)。

7
我希望能够在n维空间中计算一个(nxn)的旋转矩阵,给定以下条件:
  1. 要旋转的点。
  2. 旋转角度。
  3. 旋转轴(由n-2个跨越该子空间的单位向量组成的n-2子空间,通过原点)。
  4. 最终旋转后的点。
我认为第四个条件(最终旋转后的点)是多余的,可以不用它来计算旋转矩阵。但我有所有条件。
是否有Matlab函数已经实现了这个功能?我知道n=3时有一个函数(vrrotvec2mat)。但我没有找到适用于一般n的函数。如果没有这样的函数,有人能告诉我如何计算它,以便我可以编写函数吗?
我甚至不确定一般情况下是否存在唯一的旋转矩阵。如果有多个,我不介意使用哪个旋转矩阵。
非常感谢您的帮助。
2个回答

10
第一个问题的答案是据我所知,MATLAB没有内置函数用于构造n维旋转矩阵。然而,在下面的论文中描述了一种有趣的方法:Aguilera, Antonio和Ricardo Pérez-Aguila. "General n-dimensional rotations." (2004).。基本上,给定一组基向量,他们通过计算一系列旋转来使子空间的基向量与标准基前n-2个轴张成的子空间对齐,然后应用所需的旋转并撤销标准基准备旋转以获得最终的旋转矩阵。我实现了论文中描述的伪代码,稍微修改了一下,去掉了可选的平移分量和齐次坐标(不确定为什么这会成为旋转矩阵的一部分!)。我还将其更改为构造一个预乘旋转矩阵,而不是后乘矩阵。即我们使用y = R * x旋转列向量x。这与3维旋转的vrrotvec2mat使用的约定相匹配。
  • 子空间的基是由v给出的,它是一个nn-2的矩阵。
  • 绕子空间旋转的角度以弧度表示,为theta

% Implementation of the Aguilera-Perez Algorithm.
% Aguilera, Antonio, and Ricardo Pérez-Aguila. "General n-dimensional rotations." (2004).
function M = rotmnd(v,theta)
    n = size(v,1);
    M = eye(n);
    for c = 1:(n-2)
        for r = n:-1:(c+1)
            t = atan2(v(r,c),v(r-1,c));
            R = eye(n);
            R([r r-1],[r r-1]) = [cos(t) -sin(t); sin(t) cos(t)];
            v = R*v;
            M = R*M;
        end
    end
    R = eye(n);
    R([n-1 n],[n-1 n]) = [cos(theta) -sin(theta); sin(theta) cos(theta)];
    M = M\R*M;

我不确定这完全回答了你的问题,因为我相信有两个方向可以绕子空间旋转(或者可能更多?我甚至不知道如何思考高维空间中的旋转)。在你的问题中,基向量的方向描述了旋转方向并不清晰。
几乎肯定有一种优雅的方法来确定要使用哪个符号用于theta,但我认为您可以使用theta和-theta计算旋转矩阵,然后确定正确的旋转点。

使用示例

等价于vrrotvec2mat函数

>> R1 = rotmnd([1; 2; 3], pi/4)
R1 =
    0.7280   -0.5251    0.4407
    0.6088    0.7908   -0.0635
   -0.3152    0.3145    0.8954

>> R2 = vrrotvec2mat([1; 2; 3; pi/4])
R2 =
    0.7280   -0.5251    0.4407
    0.6088    0.7908   -0.0635
   -0.3152    0.3145    0.8954

4-d 旋转

>> v = [1 0;
        0 1;
        1 0;
        0 1];
>> R = rotmnd(v, pi/4)
R =
    0.8536   -0.3536    0.1464    0.3536
    0.3536    0.8536   -0.3536    0.1464
    0.1464    0.3536    0.8536   -0.3536
   -0.3536    0.1464    0.3536    0.8536

>> x = [0; 0; 0; 1];
>> y = R*x
y =
    0.3536
    0.1464
   -0.3536
    0.8536

有趣的注记 从论文中可以看出,主旋转矩阵的定义存在错误(它被转置了)。通过比较等式2中的旋转矩阵(即R_{1,2})和转置后的一般主轴旋转矩阵的定义,可以观察到这个错误。这个错误在实现算法时导致了一些“有趣”的问题。


P.S. 一个非常相似的方法,可能会提供一些启示,可以在以下文献中找到:

Hanson, Andrew J. "4 Rotations for N-Dimensional Graphics." Graphics Gems V. 1995. 55-64.

我还没有仔细阅读这篇文章,但我可能会稍后回来阅读并学习一些东西。


我尝试在5D中实现这个函数,但失败了。作为“v”,我在5D中生成了3个正交向量。这样正确吗? - Omry Atia
@Omry 我不确定我理解了。如果旋转矩阵是正交的且行列式为1,则旋转矩阵才是旋转矩阵。在旋转后,向量的平均值将与数据一样旋转,主成分也将如此。这意味着保留平均向量长度和协方差矩阵的行列式。 - jodag
是的,没错,它们应该被保留下来,但当我用你的代码得到的 R 在 5D 情况下乘以一个随机的 5 行矩阵时,我发现它们并没有被保留下来,因此我认为代码或算法存在问题。 - Omry Atia
是的,我刚刚检查了几个矩阵,发现 R 是行列式为 1 的正交矩阵。我想这是我的错误,我认为应该保留每个转换向量的平均值和协方差的元素 - Omry Atia
1
很高兴你解决了它 :) - jodag
显示剩余5条评论

3
如果你有正交向量u和v,它们跨越了你的n-2子空间的正交补,或者换句话说,如果w(1)…w(n-2)是跨越n-2子空间的向量,如果你有向量u和v,使得它们都与所有的w正交,并且彼此之间也正交,且长度均为1,则所需矩阵M的构造将变得简单明了。
定义nx2矩阵P以u为其第一列,v为其第二列,令R为通常的2x2旋转矩阵,通过角度旋转。然后,
M = I + P*(R-i)*P'

“这里的I是n×n的单位矩阵,i是2×2的单位矩阵。”
“如果您想,我可以详细解释一下为什么这是(唯一)您需要的矩阵。”
“如果您没有u和v向量,那么最棘手的部分就是获取它们。”
“如果您有投影矩阵Q到您的n-2维子空间,则可以通过找到Q的零空间的(正交)基础来找到u和v。然而,这里有一个令人烦恼的细节:如果您像上面那样使用u、v,则会得到一个“旋转矩阵”,而如果您交换它们,则会得到另一个旋转矩阵。我在引号中放置了旋转矩阵,因为其中一个将具有行列式1,因此是旋转矩阵,而另一个将具有行列式-1。”
“上面的矩阵将始终具有与R相同的行列式,这可以使用Sylvester's determinant identity和P'*P = i的事实来看出。”
然而,它是否代表了一个给定角度的旋转却相当模糊。假设我们选择用2xn矩阵Q而不是P来表示正交补空间的不同基础。由于它们代表同一空间的不同(正交)基础,因此存在一个2x2正交矩阵S,使得Q = S*P。因此,使用Q构造的矩阵为:
N = I + P*S'*(R-i)*S*P'

如果事实上S是一个旋转,那么一切都很好,N和M将会相同。但是如果S的行列式为-1,例如:
S = ( 0 1 )
    ( 1 0 )

"然后"
S'*(R-i)*S = R'-i

所以我们已经反转了旋转角度!

有趣!如果我错了,请纠正我,但是如果您将n-2个正交基作为矩阵W,则不是可以通过求解W的零空间来得出u和v吗? - jodag
1
@jodag 我添加了更多的内容,希望能回答你的问题。 - dmuir
谢谢!让我看看我是否理解了。假设B是我的n x (n-2)子空间(n个正交向量,它们跨越轴子空间)。令P=null(B),意思是P是一个(n x 2)的矩阵(这两个向量正交于B中的所有向量,也互相正交)。那么上面的M计算会给我所需的结果吗?只是为了澄清,我想旋转的点不一定正交于B。它可以是任何点。 - David
@David 上述计算可能会给出一个非旋转矩阵,因为M的行列式可能为-1。如果发生这种情况,则需要交换P的列。 - jodag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接