matlab - 如何在给定旋转点、旋转角度和旋转轴(n-2 子空间)的情况下计算 n 维旋转矩阵
问题描述
我想在 n 维空间中计算一个(nxn)旋转矩阵,如下所示:
- 要旋转的点。
- 一个旋转角度。
- 一个旋转轴(一个(n-2)个子空间,它通过跨子空间的(n-2) 个单位向量给定的原点)。
- 最后的旋转点。
我认为数字 4(最终旋转点)是多余的,没有它也可以计算旋转矩阵。但我都有。
是否有已经实现它的matlab函数?我知道 n=3 (vrrotvec2mat)有一个函数。但我没有找到一般n的任何功能。如果没有这样的函数,这里的任何人都可以告诉我如何计算它以便我可以编写函数?
我什至不确定一般n是否有唯一的旋转矩阵。如果有多个,我不介意使用哪个旋转矩阵。
我将不胜感激任何帮助。
提前致谢!
解决方案
第一个问题的答案是 AFAIK,没有用于构建 n 维旋转矩阵的内置 MATLAB 函数。
但是,以下论文中描述了一种有趣的方法:
阿奎莱拉、安东尼奥和里卡多·佩雷斯-阿吉拉。“一般 n 维旋转。” (2004 年)。
基本上,给定一组基向量,它们通过计算将子空间的基向量与标准基的前 n-2 个轴跨越的子空间对齐的旋转序列来描述旋转矩阵的构造,然后它们应用所需的旋转并撤消标准基础对齐旋转以获得最终的旋转矩阵。
我实现了论文中描述的伪代码,稍微修改它以删除可选的平移分量和齐次坐标(不知道为什么这会成为旋转矩阵的一部分!)。我还将它更改为构造一个预乘旋转矩阵而不是一个后乘矩阵。x
即我们使用旋转列向量y = R*x
。这符合vrrotvec2mat
用于 3 维旋转的约定。
- 子空间的基础
v
是一个n
矩阵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})与转置的通用主轴旋转矩阵的定义进行比较来观察到。这个错误在实现算法时带来了一些“乐趣”。
PS可以提供洞察力的非常相似的方法在以下内容中进行了描述:
Hanson, Andrew J. “N 维图形的 4 次旋转”。图形宝石 V. 1995. 55-64。
我还没有仔细阅读这篇文章,但我可能稍后会回来阅读这篇文章并学到一些东西。
推荐阅读
- xaml - 从 WinRTXamlToolkit 设置 ColumnChart
- vue.js - Vue 路由器如何帮助更快地加载页面?
- java - 在 ArrayList 中对 ArrayList 进行排序
- material-ui - MaterialUI 中的 CSS 过渡
- python - 在插入整数时显示错误
- python - 使用 PRAW 从文本文件中删除注释
- google-api - 使用服务帐户使用 Google Drive API 创建文件不会在授权用户帐户的 GD 上呈现文件
- javascript - Material UI 自动完成,多个默认值
- lua - 尝试在 Lua/Love2D 中绘制平台时出错
- node.js - 执行 npm start 时出现 Azure 函数节点错误