第一个问题的答案是 AFAIK,没有用于构建 n 维旋转矩阵的内置 MATLAB 函数。
但是,以下论文中描述了一种有趣的方法:
Aguilera, Antonio, and Ricardo Pérez-Aguila. "General n-dimensional rotations." (2004).
基本上,给定一组基向量,它们通过计算旋转序列来描述旋转矩阵的构造,该旋转序列将子空间的基向量与标准基的前 n-2 个轴跨越的子空间对齐,然后他们应用所需的旋转并撤消标准基础对齐旋转以获得最终的旋转矩阵。
我实现了论文中描述的伪代码,稍微修改它以删除可选的平移分量和齐次坐标(不知道为什么这会成为旋转矩阵的一部分!)。我还将它更改为构造一个预乘旋转矩阵而不是一个后乘矩阵。即我们使用y = R*x 旋转列向量x。这符合 vrrotvec2mat 用于 3 维旋转的约定。
- 子空间的基础是
v,它是一个n-by-n-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.
我还没有仔细阅读这篇文章,但我可能稍后会回来阅读这篇文章并学到一些东西。