SonicD007 464 Report post Posted June 29, 2012 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 [i]shouldn't[/i] 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. 0 Share this post Link to post Share on other sites
SillyCow 1461 Report post Posted June 29, 2012 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.) 0 Share this post Link to post Share on other sites
SonicD007 464 Report post Posted June 29, 2012 (edited) 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 [code] 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 [/code] Multiplying it by the other matrix (not sure what this is called, inverse identity?) [code] 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 [/code] 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 June 29, 2012 by SonicD007 0 Share this post Link to post Share on other sites
DevLiquidKnight 834 Report post Posted June 29, 2012 (edited) Rotate a [b]n[/b] x [b]n[/b] matrix by 90 degrees: [CODE] 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; } [/CODE] Something like this...? Edited June 29, 2012 by DevLiquidKnight 1 Share this post Link to post Share on other sites
larspensjo 1561 Report post Posted June 29, 2012 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 x0 y1 = M * y0 z1 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. 0 Share this post Link to post Share on other sites
SonicD007 464 Report post Posted June 29, 2012 [quote name='DevLiquidKnight' timestamp='1341006779' post='4954110'] Rotate a [b]n[/b] x [b]n[/b] matrix by 90 degrees: [CODE] 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; } [/CODE] Something like this...? [/quote] 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. [quote name='larspensjo' timestamp='1341009563' post='4954128'] 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 x0 y1 = M * y0 z1 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. [/quote] 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. 0 Share this post Link to post Share on other sites
DevLiquidKnight 834 Report post Posted June 29, 2012 [quote name='SonicD007' timestamp='1341011895' post='4954137'] 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?[/quote] 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. This link helped me: [url="http://theboox.com/?tag=rotate-n-by-n-matrix-90-degree-clockwise"]http://theboox.com/?tag=rotate-n-by-n-matrix-90-degree-clockwise[/url] 0 Share this post Link to post Share on other sites
clb 2147 Report post Posted June 30, 2012 [quote name='SonicD007' timestamp='1341011895' post='4954137'] 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?? [/quote] To do CW rotations, reverse the algorithm: [CODE] 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]); [/CODE] 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 [url="http://en.wikipedia.org/wiki/Rotation_matrix"]rotation matrices[/url]. 0 Share this post Link to post Share on other sites
Ryp 196 Report post Posted June 30, 2012 Hi, Just to add a little something, multiplying [u]any[/u] matrix by the identity matrix will result the exact same matrix. That's why it's called the identity matrix >< ! 0 Share this post Link to post Share on other sites
SonicD007 464 Report post Posted September 24, 2012 (edited) 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 [url="http://stackoverflow.com/questions/1457605/rotating-cordinates-around-pivot-tetris"]http://stackoverflow...nd-pivot-tetris[/url] 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 [code] **#* **** *#** **** **#* **** *#** #### **#* #### *#** **** **#* **** *#** **** [/code] 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 September 24, 2012 by SonicD007 0 Share this post Link to post Share on other sites
clb 2147 Report post Posted September 24, 2012 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. 0 Share this post Link to post Share on other sites
EpicWally 282 Report post Posted September 24, 2012 [quote name='SonicD007' timestamp='1348506682' post='4983266'] 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 [code] **#* **** *#** **** **#* **** *#** #### **#* #### *#** **** **#* **** *#** **** [/code] 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? [/quote] 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. 0 Share this post Link to post Share on other sites
SonicD007 464 Report post Posted September 24, 2012 [quote name='clb' timestamp='1348508857' post='4983280'] 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. [/quote] 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? 0 Share this post Link to post Share on other sites