7
$\begingroup$

I have a 5x5 matrix of values. I'm looking for a simple formula that I can use to rotate the position of the values (not the values themselves) 90 degrees within the matrix.

For example, here is the original matrix:

01 02 03 04 05
06 07 08 09 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

and then when the position of the values are rotated 90 degrees, it would look like this:

21 16 11 06 01
22 17 12 07 02
23 18 13 08 03
24 19 14 09 04
25 20 15 10 05

I found this post and this one, and I'm sure the answer I'm after is in there somewhere, but I've been out of university for quite a few years and am having trouble following the algorithm.

I need this for a C# program I'm writing and will be using Math.Net Numberics. I'm hoping there is just a simple rotation matrix/vector I can use to multiply my matrix with that will give me the result I'm after. Any suggestions are appreciated.

$\endgroup$
1
  • 1
    $\begingroup$ Thanks for the great answers. Afterwards I stumbled upon this other post which describes what I was looking to do using a code algorithm, which is what I was after. stackoverflow.com/questions/42519/… $\endgroup$ – deadlydog Feb 29 '16 at 2:56
9
$\begingroup$

The idea here is to find out where the values get shifted to. A location is given by two indices $(i,j)$. How to transform the indices?

Let us first try to rotate the indices around the center element:

Matrix Elements   Coordinates
01 02 03 04 05    (1,5) (2,5) (3,5) (4,5) (5,5)
06 07 08 09 10    (1,4) (2,4) (3,4) (4,4) (5,4)
11 12(13)14 15    (1,3) (2,3)((3,3))(4,3) (5,3)
16 17 18 19 20    (1,2) (2,2) (3,2) (4,2) (5,2)
21 22 23 24 25    (1,1) (2,1) (3,1) (4,1) (5,1)

Rotation by $\theta = -90^\circ$ around the origin is performed by $$ R = \left( \begin{array}{rr} \cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{array} \right) = \left( \begin{array}{rr} 0 & 1 \\ -1 & 0 \end{array} \right) $$

Plus we need coordinate translations before and after the rotation, because our index center is $(3,3)$ and not $(0,0)$, so we need homogeneous coordinates to express translations by $(\Delta x, \Delta y)$ in matrix form. First we extend the rotation to homogeneous coordinates $$ R = \left( \begin{array}{rr} 0 & 1 & 0 \\ -1 & 0 & 0 \\ 0 & 0 & 1 \end{array} \right) $$ and the translation is $$ T = \left( \begin{array}{rr} 1 & 0 & \Delta x \\ 0 & 1 & \Delta y \\ 0 & 0 & 1 \end{array} \right) $$ It acts on coordinates like this: $$ \left( \begin{array}{c} x' \\ y' \\ 1 \end{array} \right) = \left( \begin{array}{ccc} 1 & 0 & \Delta x \\ 0 & 1 & \Delta y \\ 0 & 0 & 1 \end{array} \right) \left( \begin{array}{c} x \\ y \\ 1 \end{array} \right) = \left( \begin{array}{c} x + \Delta x \\ y + \Delta y \\ 1 \end{array} \right) $$ Combining these operations we get: \begin{align} A &= T^{-1} R T \\ &= \left( \begin{array}{rrr} 1 & 0 & 3\\ 0 & 1 & 3 \\ 0 & 0 & 1 \end{array} \right) \left( \begin{array}{rrr} 0 & 1 & 0\\ -1 & 0 & 0 \\ 0 & 0 & 1 \end{array} \right) \left( \begin{array}{rrr} 1 & 0 & -3 \\ 0 & 1 & -3 \\ 0 & 0 & 1 \end{array} \right) \\ &= \left( \begin{array}{rrr} 1 & 0 & 3 \\ 0 & 1 & 3 \\ 0 & 0 & 1 \end{array} \right) \left( \begin{array}{rrr} 0 & 1 & -3 \\ -1 & 0 & 3 \\ 0 & 0 & 1 \end{array} \right) \\ &= \left( \begin{array}{rrr} 0 & 1 & 0 \\ -1 & 0 & 6 \\ 0 & 0 & 1 \end{array} \right) \end{align} The final step is to change the $y$ order: $y' = 6 - y$:

Matrix Elements   Coordinates
01 02 03 04 05    (1,1) (2,1) (3,1) (4,1) (5,1)
06 07 08 09 10    (1,2) (2,2) (3,2) (4,2) (5,2)
11 12(13)14 15    (1,3) (2,3)((3,3))(4,3) (5,3)
16 17 18 19 20    (1,4) (2,4) (3,4) (4,4) (5,4)
21 22 23 24 25    (1,5) (2,5) (3,5) (4,5) (5,5)

This affine transformation can be written in matrix form as $$ Y = \left( \begin{array}{rrr} 1 & 0 & 0 \\ 0 & -1 & 6 \\ 0 & 0 & 1 \end{array} \right) = Y^{-1} $$ This leads to \begin{align} B & = Y T^{-1} R T Y \\ &= \left( \begin{array}{rrr} 1 & 0 & 0 \\ 0 & -1 & 6 \\ 0 & 0 & 1 \end{array} \right) \left( \begin{array}{rrr} 0 & 1 & 0 \\ -1 & 0 & 6 \\ 0 & 0 & 1 \end{array} \right) \left( \begin{array}{rrr} 1 & 0 & 0 \\ 0 & -1 & 6 \\ 0 & 0 & 1 \end{array} \right) \\ &= \left( \begin{array}{rrr} 1 & 0 & 0 \\ 0 & -1 & 6 \\ 0 & 0 & 1 \end{array} \right) \left( \begin{array}{rrr} 0 & -1 & 6 \\ -1 & 0 & 6 \\ 0 & 0 & 1 \end{array} \right) \\ &= \left( \begin{array}{rrr} 0 & -1 & 6 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{array} \right) \end{align} A matrix element at indices $(i,j)$ ($i$-th row, $j$-th column) has coordinates $(j, i)$. Thus the index transformation $(i,j) \to (i', j')$ is $$ \left( \begin{array}{r} j' \\ i' \\ 1 \end{array} \right) = \left( \begin{array}{rrr} 0 & -1 & 6 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{array} \right) \left( \begin{array}{r} j \\ i \\ 1 \end{array} \right) $$ or $$ \begin{align} i' &= j \\ j' &= 6 - i \end{align} $$

A possible algorithm to calculate the rotated matrix b from a given matrix a is:

(1,5).each do |i| 
  (1,5).each do |j| 
    b[j, 6-i] = a[i, j]
  end
end

Here is some test code online: (link) Click the tab marked "Execute" to run it.

Example:

Let us do the calculation for the 18-th element:

Matrix Elements   Matrix Indices
01 02 03 04 05    (1,1) (1,2) (1,3) (1,4) (1,5)
06 07 08 09 10    (2,1) (2,2) (2,3) (2,4) (2,5)
11 12 13 14 15    (3,1) (3,2) (3,3) (3,4) (3,5)
16 17(18)19 20    (4,1) (4,2)((4,3))(4,4) (4,5)
21 22 23 24 25    (5,1) (5,2) (5,3) (5,4) (5,5)

This entry is the matrix element $a_{4 3}$. The indices are $(i, j) = (4,3)$.

The rotated matrix is

21 16 11 06 01
22 17 12 07 02
23(18)13 08 03
24 19 14 09 04
25 20 15 10 05

The value is now at $b_{3 2}$, thus $(i', j') = (3,2)$. This agrees with the found transformation.

What did the transformation do? First, if the lower left element of the original matrix (the one containing value $21$) is at coordinates $(x,y) = (1,1)$, we want to have element $18$ at coordinates $(x, y) = (3,2)$. So original $(i,j) = (4,3)$ is interpreted as coordinates $(x,y)=(3,4)$ and flipped by $Y$ to coordinates $(3,2)$. Then $T$ translates it to coordinates $(0,-1)$, which is fine as it sits under the central element (center now at $(0,0)$). $R$ rotates it to $(-1,0)$, which is left from the central element (center now at $(0,0)$), fine again. $T^{-1}$ translates it back to $(x'.y')=(2,3)$ which is still left to the center. The final $Y^{-1} = Y$ changes nothing, as we are on the middle row. Final translation to matrix indices gives $(i',j') = (3,2)$.

$\endgroup$
5
  • $\begingroup$ I downvoted because I agree with Théophile. If the answer changes to answer the OP's question I will remove the downvote. $\endgroup$ – Spencer Feb 29 '16 at 0:47
  • $\begingroup$ @mvw, is your answer unfinished? $\endgroup$ – Spencer Feb 29 '16 at 0:48
  • $\begingroup$ @mvw, ok I've removed the downvote for now. When I evaluated the answer I thought it was complete. $\endgroup$ – Spencer Feb 29 '16 at 0:59
  • $\begingroup$ Ah, interesting. It's very clear now. :) That being said, it's surely much faster to just do some quick reasoning rather than multiply all those matrices... Anyway, it works! $\endgroup$ – Théophile Feb 29 '16 at 4:25
  • $\begingroup$ Each matrix represents a transformation, and I wanted to show how to come up with the final formula, by expressing it as result of a series of transformations. From this one should be able to vary the task, like different matrix dimension, different rotation angle, different center of rotation etc. $\endgroup$ – mvw Feb 29 '16 at 5:53
7
$\begingroup$

Transpose the matrix, then reverse the order of the columns. So $$M\mapsto M^T\begin{bmatrix}0&0&\cdots&0&1\\0&0&\cdots&1&0\\\vdots&\vdots&&\vdots&\vdots\\0&1&\cdots&0&0\\1&0&\cdots&0&0\end{bmatrix}$$ For instance $$\begin{bmatrix}a&b&c\\d&e&f\\g&h&i\end{bmatrix}\mapsto\begin{bmatrix}a&b&c\\d&e&f\\g&h&i\end{bmatrix}^T\begin{bmatrix}0&0&1\\0&1&0\\1&0&0\end{bmatrix}=\begin{bmatrix}a&d&g\\b&e&h\\c&f&i\end{bmatrix}\begin{bmatrix}0&0&1\\0&1&0\\1&0&0\end{bmatrix}=\begin{bmatrix}g&d&a\\h&e&b\\i&f&c\end{bmatrix}$$

$\endgroup$
1
  • $\begingroup$ @vaughnmcbob1 You are mistaken. $\endgroup$ – alex.jordan Jul 4 '18 at 22:11
5
$\begingroup$

A rotation by 90 degrees can be accomplished by two reflections at a 45 degree angle so if you take the transpose of the matrix and then multiply it by the permutation matrix with all ones on the minor diagonal and all zeros everywhere else you will get a clockwise rotation by 90 degrees. For a 2x2 matrix this would look like:

A B
C D

Transpose:

A C
B D

Permute, reversing order of columns:

C A
D B

However, in a programming context, it would probably be better to solve this problem by moving the data around.

$\endgroup$
2
  • $\begingroup$ Thank you for this answer. Easiest to implement by far in a program, at least for square matrices. Simply do x_new = y; y_new = m_size - 1 - x;, where x and y are indices and m_size is number of rows (which equals number of columns). Assuming 0-index. $\endgroup$ – cyqsimon Feb 20 at 4:29
  • $\begingroup$ Correction: what I wrote in the previous comment was in fact rotate by -90dgrs. The actually correct logic for rotating by 90dgrs is x_new = m_size - 1 - y; y_new = x;. $\endgroup$ – cyqsimon Feb 20 at 8:20
0
$\begingroup$

As best I understand the question, it's about how to transpose a matrix around its secondary diagonal. If I'm right, it might be something like this: $I^{T^{*}}=I_0A^TI_0$, where $(I_0)_{ij}=\delta_{n+1-i-j}$

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.