• Create Account

Matrix rotation (Tetris)

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

12 replies to this topic

#1SonicD007  Members   -  Reputation: 457

Like
0Likes
Like

Posted 29 June 2012 - 02:56 PM

Hey everyone. I'm working on the rotation of the pieces in tetris and I'm trying to use matrix math to figure out the rotation for the array. I never learned matrix math though so I probably shouldn't be trying to do this but I'm going for it anyway.

From what I've gathered, if I have a 3x3 matrix, I first transpose it.
After the transposition, I should multiply it by:
0,0,1
0,1,0
1,0,0
if I want a clockwise rotation from the original matrix.
If I want a counter-clockwise rotation, I would multiply the transposed matrix by
1,0,0
0,1,0
0,0,1

Now for a 4x4 matrix, this doesn't work. My question is, how can I do this with a 4x4 matrix? (Keep in mind I don't know much about matrix math so if you can dumb it down or provide links that would be great).

I tried multiplying by
0,0,0,1
0,0,1,0
0,1,0,0
1,0,0,0
but that's incorrect.

I appreciate the help.

#2SillyCow  Members   -  Reputation: 849

Like
0Likes
Like

Posted 29 June 2012 - 03:16 PM

It is unclear on what you are trying to achieve.
What are you trying to rotate in your Tetris game?

A small suggestion: If you are making only 90 degree rotations, There are very simple ways of doing it. (No matrices or trigonometry involved.)

My new android game : Enemies of the Crown

My previous android game : Killer Bees

#3SonicD007  Members   -  Reputation: 457

Like
0Likes
Like

Posted 29 June 2012 - 03:38 PM

I have a Piece class that holds an array that represents the shape of each falling block. An example of what my array would look like for the "T" shape would look like this:
0,1,0
1,1,1
0,0,0

So for what I was trying to explain was if I transpose this array and then multiply it by the 1 array (I think it's called the identity matrix), I would get it's rotation
Ex:
The above array transposed would be
0,1,0
1,1,0
0,1,0
multiply that by the identity matrix gives the right rotation
0,1,0	 0,0,1	 0,1,0
1,1,0 X  0,1,0 = 0,1,1
0,1,0	 1,0,0	 0,1,0

Multiplying it by the other matrix (not sure what this is called, inverse identity?)
0,1,0	 1,0,0	 0,1,0
1,1,0 X  0,1,0 = 1,1,0
0,1,0	 0,0,1	 0,1,0

Some of my shapes are 3x3 while others are 4x4. I thought using matrix math would be a better approach than hard coding the shap rotations into their own arrays.

So my question is, what would be the identity matrix for the 4x4 matrix so I can rotate by pieces that are 4x4 blocks in size?

Edited by SonicD007, 29 June 2012 - 03:39 PM.

#4DevLiquidKnight  Members   -  Reputation: 834

Like
1Likes
Like

Posted 29 June 2012 - 03:52 PM

Rotate a n x n matrix by 90 degrees:
for(int i=0; i < N/2; i++)
for(int j=0; j < (N+1)/2; j++)
cyclic_roll(a[i][j], a[N-1-j][i], a[N-1-i][N-1-j], a[j][N-1-i]);

void cyclic_roll(int &a, int &b, int &c, int &d)
{
int temp = a;
a = b;
b = c;
c = d;
d = temp;
}


Something like this...?

Edited by DevLiquidKnight, 29 June 2012 - 03:58 PM.

#5larspensjo  Members   -  Reputation: 1540

Like
0Likes
Like

Posted 29 June 2012 - 04:39 PM

Matrix math doesn't work like that. When you have a transformation matrix, you multiply it with a coordinate, and get another coordinate. An object, like a "T", could be described with 4 coordinates. You have to multiply each of these with the transformation matrix, to get a new set of 4 coordinates.
[source lang="java"][font=courier new,courier,monospace]x1 x0y1 = M * y0z1 z0[/font][/source]
Where "M" is a 3x3 transformation matrix. You only need a 3x3 matrix if you are going to do rotations, translations and scaling.

However, in your application, it looks like using transformation matrices is an overkill.
Current project: Ephenation.
Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/

#6SonicD007  Members   -  Reputation: 457

Like
0Likes
Like

Posted 29 June 2012 - 05:18 PM

Rotate a n x n matrix by 90 degrees:

for(int i=0; i < N/2; i++)
for(int j=0; j < (N+1)/2; j++)
cyclic_roll(a[i][j], a[N-1-j][i], a[N-1-i][N-1-j], a[j][N-1-i]);

void cyclic_roll(int &a, int &b, int &c, int &d)
{
int temp = a;
a = b;
b = c;
c = d;
d = temp;
}


Something like this...?

That algorithm is so weird yet it works. I tried it on a 3x3 array and 4x4 array on pen and paper and it rotated both arrays CCW. Where did you learn about that from and how can I change this algorithm to do CW rotations?? This is exactly what I was looking for.

Matrix math doesn't work like that. When you have a transformation matrix, you multiply it with a coordinate, and get another coordinate. An object, like a "T", could be described with 4 coordinates. You have to multiply each of these with the transformation matrix, to get a new set of 4 coordinates.
[source lang="java"][font=courier new,courier,monospace]x1 x0y1 = M * y0z1 z0[/font][/source]
Where "M" is a 3x3 transformation matrix. You only need a 3x3 matrix if you are going to do rotations, translations and scaling.

However, in your application, it looks like using transformation matrices is an overkill.

It is overkill I admit, but I was hoping that I could reuse the code in the future with any size array instead of limiting myself to just this application.

#7DevLiquidKnight  Members   -  Reputation: 834

Like
0Likes
Like

Posted 29 June 2012 - 05:28 PM

That algorithm is so weird yet it works. I tried it on a 3x3 array and 4x4 array on pen and paper and it rotated both arrays CCW. Where did you learn about that from and how can I change this algorithm to do CW rotations?

Just did some searching online, and thought about the logic a little bit, plus I am pretty certain MATLAB has a function just like this. I have used this function before. You are basically just moving stuff around. I'm sure its probably pretty easy to modify to rotate however you want the basic logic is their just have to change it around.

http://theboox.com/?tag=rotate-n-by-n-matrix-90-degree-clockwise

#8clb  Members   -  Reputation: 1781

Like
0Likes
Like

Posted 30 June 2012 - 01:15 AM

That algorithm is so weird yet it works. I tried it on a 3x3 array and 4x4 array on pen and paper and it rotated both arrays CCW. Where did you learn about that from and how can I change this algorithm to do CW rotations??

To do CW rotations, reverse the algorithm:

for(int i=0; i < N/2; i++)
for(int j=0; j < (N+1)/2; j++)
cyclic_roll(a[j][N-1-i], a[N-1-i][N-1-j], a[N-1-j][i], a[i][j]);


The way that algorithm works is that considers the matrix as four quadrants, and shuffles the elements around between quadrants like the rotation will do.

As noted above, this is 'matrix rotation' in the literal meaning of terms, not to be confused with rotation matrices.
Me+PC=clb.demon.fi | C++ Math and Geometry library: MathGeoLib, test it live! | C++ Game Networking: kNet | 2D Bin Packing: RectangleBinPack | Use gcc/clang/emcc from VS: vs-tool | Resume+Portfolio | gfxapi, test it live!

#9Ryp  Members   -  Reputation: 190

Like
0Likes
Like

Posted 30 June 2012 - 04:45 AM

Hi,

Just to add a little something, multiplying any matrix by the identity matrix will result the exact same matrix. That's why it's called the identity matrix >< !

#10SonicD007  Members   -  Reputation: 457

Like
0Likes
Like

Posted 24 September 2012 - 11:11 AM

Hey everyone,

I have another question regarding this same topic. I got the rotation working using the cyclic roll (as mentioned in this topic) and my Tetris game has been going well so far. Now I noticed that using the method in this post, my tetris piece will rotate, but its rotated location isn't the location of where it was before. I know I need to offset it but I don't really understand how. I've been looking at http://stackoverflow...nd-pivot-tetris for a bit but nothing is clicking for me at the moment and my brain is getting fried thinking about it.

Can anyone tell me the steps to get the output I want or help explain how to do this? Maybe I need some time to think on that post but right now my brain is NOT working! =/

Here is what my rotation looks like for a line
**#*	 ****	 *#**	 ****
**#*	 ****	 *#**	 ####
**#*	 ####	*#**	 ****
**#*	 ****	 *#**	 ****


That is exactly how it's showing on my playing field when I rotate, you can see the piece will move slightly when rotated. How do I fix this? Do I adjust my rotation algorithm or do I leave the rotation alone and offset it somehow when I'm drawing it/using it in the game?

Edited by SonicD007, 24 September 2012 - 11:13 AM.

#11clb  Members   -  Reputation: 1781

Like
0Likes
Like

Posted 24 September 2012 - 11:47 AM

If you want to go the matrix route, the general method is to "translate the origin", i.e. since a cardinal rotation matrix rotates about a single world axis passing through the world origin (0,0), and you want to rotate about the point p, you'll temporarily make point p the origin, then rotate, and then translate back. In matrix math, using the M*v convention, the formula is M = T(p) * R * T(-p), where T(p) translates by the point p, and R is the original rotation matrix about the origin.

Alternatively, and what might be easier, just manually compute the offsets you want to perform after each rotation, and store them in some precomputed table.
Me+PC=clb.demon.fi | C++ Math and Geometry library: MathGeoLib, test it live! | C++ Game Networking: kNet | 2D Bin Packing: RectangleBinPack | Use gcc/clang/emcc from VS: vs-tool | Resume+Portfolio | gfxapi, test it live!

#12EpicWally  Members   -  Reputation: 282

Like
0Likes
Like

Posted 24 September 2012 - 11:50 AM

Hey everyone,
I have another question regarding this same topic. I got the rotation working using the cyclic roll (as mentioned in this topic) and my Tetris game has been going well so far. Now I noticed that using the method in this post, my tetris piece will rotate, but its rotated location isn't the location of where it was before. I know I need to offset it but I don't really understand how. I've been looking at http://stackoverflow...nd-pivot-tetris for a bit but nothing is clicking for me at the moment and my brain is getting fried thinking about it.
Can anyone tell me the steps to get the output I want or help explain how to do this? Maybe I need some time to think on that post but right now my brain is NOT working! =/
Here is what my rotation looks like for a line

**#*	 ****	 *#**	 ****
**#*	 ****	 *#**	 ####
**#*	 ####    *#**	 ****
**#*	 ****	 *#**	 ****

That is exactly how it's showing on my playing field when I rotate, you can see the piece will move slightly when rotated. How do I fix this? Do I adjust my rotation algorithm or do I leave the rotation alone and offset it somehow when I'm drawing it/using it in the game?

This was one of the reasons I didn't bother with rotation algorithms when I tried tetris. I programmed a certain number of states into each shape (4 for the T, and both Ls, 2 for the Z pieces and the line, and 1 for the square) and had the "rotate" button just change states. Primitive? Perhaps, but it achieved the desired result. I like the elegance of the approach you are taking, but functionally I think it creates more problems than it's worth.

#13SonicD007  Members   -  Reputation: 457

Like
0Likes
Like

Posted 24 September 2012 - 12:21 PM

If you want to go the matrix route, the general method is to "translate the origin", i.e. since a cardinal rotation matrix rotates about a single world axis passing through the world origin (0,0), and you want to rotate about the point p, you'll temporarily make point p the origin, then rotate, and then translate back. In matrix math, using the M*v convention, the formula is M = T(p) * R * T(-p), where T(p) translates by the point p, and R is the original rotation matrix about the origin.

Alternatively, and what might be easier, just manually compute the offsets you want to perform after each rotation, and store them in some precomputed table.

Can you show me an example? Is there any way I can use the matrix I already get from rotating and offset that somehow or is this the only way?

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS