6

I would like to calculate an (nxn) rotation matrix in the n-dimensional space given the following:

  1. The point to rotate.
  2. An angle of rotation.
  3. An axis of rotation (an (n-2) subspace that passes through the origin given by (n-2) unit vectors that span the subspace).
  4. 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!

David
  • 451
  • 3
  • 11

2 Answers2

8

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 an n-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.

jodag
  • 11,876
  • 3
  • 28
  • 45
  • This is very interesting! Thanks! – Cris Luengo May 15 '18 at 06:42
  • Thanks! I tried your code with many examples for 3D. I compared the results with the one I already have for 3D and I got exactly the same rotation matrix in all of them :). didn't see any issue with the sign of theta. I'm now checking it for higher dimensions. thanks! – David May 17 '18 at 15:57
  • I have tried to implement this function in 5D, and failed. as `v` I generated 3 orthogonal vectors in 5D. Is this correct? – Omry Atia Jul 27 '18 at 13:29
  • @Omry Yes `v` should be a 5x3 matrix of rank 3. When you say it didn't work do you mean you got a result different than expected or that the code I provided caused an error? – jodag Jul 27 '18 at 13:54
  • Yes I constructed 3 5D vectors by GramSchmidt and used them as `v`. I then calculated `R` and got a matrix which I am sure is not a rotation matrix. How do I know? because when I applied it do a random matrix with 5 rows, the means and covariances of the vectors changed with respect to before the rotation – Omry Atia Jul 27 '18 at 13:58
  • @Omry I'm not sure I follow. A rotation matrix is a rotation matrix if and only if it is orthogonal and has determinate of 1. The mean of the vectors after a rotation will be rotated the same as the data, as will the principal components. This implies that the length of the mean vector and determinate of the covariance matrix will be preserved. – jodag Jul 27 '18 at 21:36
  • Yes, exactly, they should be preserved, but when I multiplied `R` which I got from your code for the 5D case by a random 5 row matrix, I found that they were not preserved, and therefore I believe there is a problem with either the code or the algorithm – Omry Atia Jul 28 '18 at 06:08
  • @Omry Just to reiterate the mean and covariance matrix should **not** be preserved, only their magnitude and determinate respectively. Can you verify that the rotation matrix is orthogonal with determinate one? You can check this by verifying that `R*transpose(R)` is an identity matrix and `det(R)` is `1`. If not can you give the matrix `v` that you're using. I've run many checks in the 5D case and I always get a valid rotation matrix. – jodag Jul 28 '18 at 06:32
  • Yes, I just checked on several matrices and `R` is orthogonal with determinant `1`. I guess it was my mistake, I thought the mean of *each* transformed vector and the *elements* of the covariance should be preserved – Omry Atia Jul 28 '18 at 06:40
  • 1
    Glad you got it figured out :) – jodag Jul 28 '18 at 06:42
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!

dmuir
  • 3,453
  • 2
  • 13
  • 11
  • Interesting! Please correct me if I'm wrong, but if you have the n-2 orthonormal basis as as a matrix W, then wouldn't you be able to come up with u and v by solving for the null space of W? – jodag May 15 '18 at 15:24
  • 1
    @jodag I added some more that I hope answers your question. – dmuir May 15 '18 at 16:52
  • Thanks! let me see if I understand it. say B is my n x (n-2) subspace (n orthogonal vectors that span the axis subspace). and let P=null(B) meaning, P is a matrix of (n x 2) (the 2 vectors that orthogonal to all the vectors in B and also to each other). then the above calculation of M will give me what I need? Just to clarify, the point that I want to rotate is not necessarily orthogonal to B. it can be any point. – David May 17 '18 at 15:35
  • @David The above calculation may give you a non-rotation matrix since the determinate of M may be -1. If this happens then you need to swap the columns of P. – jodag May 17 '18 at 19:40