第一个问题的答案是据我所知,MATLAB没有内置函数用于构造n维旋转矩阵。然而,在下面的论文中描述了一种有趣的方法:
Aguilera, Antonio和Ricardo Pérez-Aguila. "General n-dimensional rotations." (2004).。基本上,给定一组基向量,他们通过计算一系列旋转来使子空间的基向量与标准基前n-2个轴张成的子空间对齐,然后应用所需的旋转并撤销标准基准备旋转以获得最终的旋转矩阵。我实现了论文中描述的伪代码,稍微修改了一下,去掉了可选的平移分量和齐次坐标(不确定为什么这会成为旋转矩阵的一部分!)。我还将其更改为构造一个预乘旋转矩阵,而不是后乘矩阵。即我们使用
y = R * x
旋转列向量
x
。这与3维旋转的
vrrotvec2mat
使用的约定相匹配。
- 子空间的基是由
v
给出的,它是一个n
乘n-2
的矩阵。
- 绕子空间旋转的角度以弧度表示,为
theta
。
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
R1 =
0.7280 -0.5251 0.4407
0.6088 0.7908 -0.0635
-0.3152 0.3145 0.8954
>> R2 = vrrotvec2mat([1
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.
我还没有仔细阅读这篇文章,但我可能会稍后回来阅读并学习一些东西。
R
在 5D 情况下乘以一个随机的 5 行矩阵时,我发现它们并没有被保留下来,因此我认为代码或算法存在问题。 - Omry AtiaR
是行列式为1
的正交矩阵。我想这是我的错误,我认为应该保留每个转换向量的平均值和协方差的元素。 - Omry Atia