问题
I would like to calculate an (nxn) rotation matrix in the n-dimensional space given the following:
- The point to rotate.
- An angle of rotation.
- An axis of rotation (an (n-2) subspace that passes through the origin given by (n-2) unit vectors that span the subspace).
- the final rotated point.
I think that number 4 (the final rotated point) is redundant and it is possible to calculate the rotation matrix without it. But I have them all.
Is there a matlab function that already implements it? I know that there's a function for n=3 (vrrotvec2mat). But I didn't find any function for the general n. If there's no such function, anyone here can show me how to calculate it so I can write the function?
I'm not even sure if there's a unique rotation matrix for the general n. If there's more than one, I don't mind which rotation matrix to use.
I would appreciate any help.
Thanks in advance!
回答1:
The answer to the first question is AFAIK there's no builtin MATLAB function for constructing a n-dimensional rotation matrix.
There is, however, an interesting approach described in the following paper:
Aguilera, Antonio, and Ricardo Pérez-Aguila. "General n-dimensional rotations." (2004).
Basically, given a set of basis vectors, they describe the construction of a rotation matrix by computing a sequence of rotations which aligns the basis vectors of the subspace with the subspace spanned by the first n-2 axes of the standard basis, then they apply the desired rotation and undo the standard basis alignment rotations to get the final rotation matrix.
I implemented the pseudocode described in the paper, modifying it slightly to remove the optional translation component and homogeneous coordinates (not sure why this would be part of the rotation matrix anyway!). I also changed it to construct a premultiply rotation matrix rather than a postmultiply matrix. i.e. We rotate a column vector x
using y = R*x
. This matches the convention used by vrrotvec2mat
for 3-dimensional rotation.
- The basis of the subspace is given as
v
which is ann
-by-n-2
matrix. - The angle of rotation about the subspace is given as
theta
in radians.
% 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;
I'm not sure if this completely answers your question as I believe there are two directions to rotate about a subspace (or maybe more? I don't even really know how to think about a rotation in higher dimensional space). In your question it's not clear that the direction of the basis vectors describe the direction of rotation.
There's almost certainly an elegant way to determine which sign to use for theta
, but I think you could just compute the rotation matrix with both theta
and -theta
, then determine which correctly goes from the point you want to rotate to the final rotated point.
Usage Examples
equivalence to 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 rotation
>> 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
Interesting note From the paper there appears to be a mistake in the definition of the general matrix for main rotations (it's transposed). This can be observed by comparing the rotation matrix in Eq.2 (which is R_{1,2}) to the definition of the general main axis rotation matrix which is transposed. This mistake led to some "fun" while implementing the algorithm.
P.S. A very similar approach which may provide insight is described in:
Hanson, Andrew J. "4 Rotations for N-Dimensional Graphics." Graphics Gems V. 1995. 55-64.
I have yet to read this carefully, but I might come back later to read this and learn something.
回答2:
if you had orthonormal vectors u and v that span the orthogonal complement of your n-2 subspace, or put another way, if w(1) .. w(n-2) are the vectors that span the n-2 subspace, if you had vectors u and v so that both were orthogonal to all of the w's, and orthogonal to each other and each of length 1, then the contstuction of the required matrix M would be straightfoward.
Define the nx2 matrix P to have u as it's first column and v as its second, and let R be the usual 2x2 rotation matrix through the angle. Then
M = I + P*(R-i)*P'
(here I is the nxn identity and i the 2x2 one)
(If you want I'll expand on this answer to argue why that is the (unique) matrix you need).
The tricky part would be getting hold of the vectors u and v if you don't aleady have them.
If you have the projection matrix Q onto your n-2 dim subspace then yu could find u and v by finding a (orthonormal) basis for the null-space of Q. However there is an irritating detail here. If you use u, v as above you will get one 'rotation matrix' whereas if you swap them you will a different one. I put rotation matrix in quotes because one of these will have determinant 1, and so be a rotation, and the other will have determinant -1.
The matrix above will always have the same determinant as R, as can be seen using Sylvester's determinant identity and the fact that P'*P = i.
However whether it represents a rotation through a given angle is rather murky. Suppose one chose a different basis for the orthogonal complement, and so used a 2xn matrix Q instead of P. Since these represent different (orthogonal) bases of the same space there is a 2x2 orthogonal matrix S say with Q = S*P. So the matrix constructed using Q is
N = I + P*S'*(R-i)*S*P'
If, in fact, S is a rotation, all is well and N and M will be the same. But if S has determinant -1, eg
S = ( 0 1 )
( 1 0 )
Then
S'*(R-i)*S = R'-i
and so we have reversed the angle of rotation!
来源:https://stackoverflow.com/questions/50337642/how-to-calculate-a-rotation-matrix-in-n-dimensions-given-the-point-to-rotate-an