Is there any easy way to rotate the values of a matrix/array?

292 views Asked by At

So, let's say I have the following matrix/array -

    [0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 1 1 1 0 0 0 0 0
     0 0 0 1 1 1 1 0 0 0 0 0
     0 0 1 1 1 1 1 1 0 0 0 0
     0 0 1 1 1 1 1 1 0 0 0 0
     0 0 0 1 1 1 1 0 0 0 0 0 
     0 0 0 0 1 1 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 0 0]

It would be fairly trivial to write something that would translate these values up and down. What if I wanted to rotate it by an angle that isn't a multiple of 90 degrees? I know that It is obviously impossible to get the exact same shape (made of 1s), because of the nature of the grid. The idea that comes to mind is converting each value of 1 to a coordinate vector. Then it would amount to rotating the coordinates (which should be more simple) about a point. One could then write something which would take the coordinates, and compare them to the matrix grid, and if there is a point in the right box, it will be filled. I know I'll also have to find a center around which to rotate.

Does this seem like a reasonable way to do this? If anyone has a better idea, I'm all ears. I know with a small grid like this, the shape would probably be entirely different, however if I had a large shape represented by 1s, in a large grid, the difference between representations would be smaller.

2

There are 2 answers

0
AudioBubble On

I think this should work:

from math import sin, cos, atan2, radians
i0,j0 = 0,0 #point around which you'll rotate
alpha = radians(3) #3 degrees

B = np.zeros(A.shape)
for i,j in np.swapaxes(np.where(A==1),0,1):
    di = i-i0
    dj = j-j0
    dist = (di**2 + dj**2)**0.5
    ang = atan2(dj,di)

    pi = round(sin(ang+alpha)*dist) + i0
    pj = round(cos(ang+alpha)*dist) + j0
    B[pi][pj] = 1

But, please, don't forget about segmentation fault!

B array should be much bigger than A and origin should be (optimally) in the middle of the array.

0
Luke On

First of all, rotating a shape like that with only 1's and 0's at non 90 degree angles is not really going to look much like the original at all, when it's done at such a low "resolution". However, I would recommend looking into rotation matrices. Like you said, you would probably want to find each value as a coordinate pair, and rotate it around the center. It would probably be easier if you made this a two-dimensional array. Good luck!