Stuby085

I am using two dimensional arrays to create Tetris style blocks that need to be rotated. I've thought of a number of things, but nothing has worked. I am now asking for help. Since rotation of two dimensional arrays sounds odd, I'll try to make some ASCII text for visualization. Each number represents an element in the array. I'll give two examples.

Before rotation: After rotation:

0 1 2 6 3 0
3 4 5 7 4 1
6 7 8 8 5 2


Before rotation: After rotation:

0 1 2 3 0
3 4 5 4 1
5 2

Can someone please explain to me how to get from the before to the after


Re: Visual C# General Rotating Two Dimensional Arrays

Stuby085

After reviewing my notes from before my post I'm come to the conclusion that the following for loop will work, however it doesn't and I'm not sure why.

for (int y = 0; y < rotatedShape.Rank; y++)
{
for (int x = 0; x < rotatedShape.Length / rotatedShape.Rank; x++)
{
rotatedShape[x, y] = currentShape[y,
rotatedShape.Length / rotatedShape.Rank - 1 - x];
}
}


My only speculation is that I am unsure how to get the width of a two dimensional array. On dimension is easy, you just use the Length of the array, but that gives the area of a multidimensional array.




Re: Visual C# General Rotating Two Dimensional Arrays

NeederOfVBHelp

I havn't went over your code t0o long BUT... just a guess: you you need to make a copy of the array before you start rotating code, DO NOT make changes to the copy, update the orgiginal array by reading off of the copy,

hope this helps





Re: Visual C# General Rotating Two Dimensional Arrays

Stuby085

sorry, but i do not follow what you mean




Re: Visual C# General Rotating Two Dimensional Arrays

NeederOfVBHelp

//this is your original data, this is what you want to rotate

int [,] OriginalThing = new int[5,5];

//make a temporary read only data holder

int [,] TempArray = new int[5,5];

//copy the data into it

int xcount = 0;

while (xcount <= 4)

{

int ycount = 0;

while (ycount <= 4)

{

TempArray[xcount, ycount] = OriginalThing[xcount, ycount];

ycount++;

}

xcount++;

}

//now do your thing, ONLY READ from TempArray, ONLY WRITE to OriginalThing

OriginalThing[SomeX, SomeY] = TempArray[OtherX, OtherY]; //As you may of guessed, this last peice of code won't actually rotate it, but the point is OriginalThing is always on the LEFT, and TempArray is only on the RIGHT





Re: Visual C# General Rotating Two Dimensional Arrays

A. de Winkel

of course a copy is needed, I work often with arrays.

I never figured out the following though suppose the forementioned rotator is implemented in a method



private int[,] rotater(int[,] ar)
{
  int[,] tgt = new int[ar.Length / ar.Rank, ar.Rank];
//....

  return tgt;
}

 

According to what I know I can get only the length and the superfluous rank (which here is 2 of course here)

but when the Length is say 100 I could have fed the routine with the following possiblities

int[1,100] 

int[2,50]

int[4,25]

int[5,20]

int[10,10]

and the 4 obvious more, given the Length and Rank (2) I can't figure which of these 9 possibilities I fed the routine with

values I need to figure to dimension tgt correctly to make the above work for all.

 

note, this is but a simple sample of my multidimensional problem. of course one can add a parameter to the routine

which I now need to do, but is far less fun.





Re: Visual C# General Rotating Two Dimensional Arrays

A. de Winkel

EDIT FUNCTIONALITY DOES NOT WORK SO I HAD TO REPLY!

here the complete solution:

void TestRotate()
{
int[,] org = { { 1, 2 }, { 2, 3 }, { 4, 5 } };
int[,] tgt = rotater(org);
string s = "";
int dm1 = org.Rank, dm2 = org.Length / dm1;
for (int i = 0; i < dm1; i++)
for (int j = 0; j < dm2; j++)
s += tgt[i, j].ToString() + ((j == dm2 - 1) "\r\n" : "");
MessageBox.Show(s);
}
int[,] rotater(int[,] org)
{
int dm1 = org.Rank, dm2 = org.Length / dm1;
int[,] tgt = new int[dm1, dm2];
for (int i = 0; i < dm1; i++)
for (int j = 0; j < dm2; j++)
tgt[i, j] = org[j, i];
return tgt;
}
int[,] rotater(int dm1,int[,] org)
{
int dm2 = org.Length / dm1;
int[,] tgt = new int[dm1, dm2];
for (int i = 0; i < dm1; i++)
for (int j = 0; j < dm2; j++)
tgt[i, j] = org[j, i];
return tgt;
}
Th first routine I prefer, but can't figure dm1 inside the routine, so I currently need the 2nd override to generalize for all possibilities.





Re: Visual C# General Rotating Two Dimensional Arrays

TilakGopi

Hi,

The following code does ur job.Doesn't it

[Code language = C#]

static void Main()

{

int[,] NormalShape = new int[2,3];

Console.WriteLine("Normal array is:");

for (int i = 0; i < 2; i++)

{

for (int j = 0; j < 3; j++)

{

NormalShape[i, j] = i * 10 + j;

Console.Write(NormalShape[i, j] + "\t");

}

Console.WriteLine();

}

Console.WriteLine("Rotated array is:");

int[,] rotatedShape = new int[3,2];

for (int i = 0; i < 3; i++)

{

for (int j = 0; j < 2; j++)

{

rotatedShape[i, j] = NormalShape[j, i];

Console.Write(rotatedShape[i, j] + "\t");

}

Console.WriteLine();

}

}

[/Code]

Thanx,

Ch.T.Gopi Kumar.






Re: Visual C# General Rotating Two Dimensional Arrays

Matthew Watson

Performance warning:

If you want the fastest code, you should use jagged arrays rather than multidimensional arrays.

i.e. use code like this:



int rows = 10;
int cols = 10;
int [][] matrix = new int[rows][];

for (int row = 0; row < rows; ++rows)
    matrix[row] = new int[cols];

 


See http://msdn2.microsoft.com/en-us/library/ms182277(vs.80).aspx
and http://www.odetocode.com/Articles/253.aspx

(There are many other articles, just google for: jagged multidimensional performance)




Re: Visual C# General Rotating Two Dimensional Arrays

A. de Winkel

nice but still up to specialized array. (how on earth did you copy that code in a decent fashion)

here (unfortunately garbled) one step further, all 8 possible "aspectial variants" of a given array:


int[,] Aspects(int dim, int[,] org, bool trans, int reflec)
{
  int dm1 = (trans) dim : org.Length / dim,
      dm2 = (trans) org.Length / dim : dim;
  bool xref = (reflec & 1) == 1, yref = (reflec & 2) == 2;
  int[,] tgt = new int[dm1, dm2];
  for (int i = 0; i < dm1; i++)
     for (int j = 0; j < dm2; j++)
     if (trans)
       tgt[i, j] = org[(xref) dm2 - 1 - j : j,
                         (yref) dm1 - 1 - i : i];
    else

       tgt[i, j] = org[(xref) dm1 - 1 - i : i,
                         (yref) dm2 - 1 - j : j];
  return tgt;
}
void TestAspects()
{
  int[,] org = { { 1, 2 }, { 2, 3 }, { 4, 5 } };
  string s = "";
  for (int aspect = 0; aspect < 8; aspect++)
  {
     s +=
"Aspect " + aspect.ToString() + "\r\n";
     int[,] tgt = Aspects(2, org, (aspect & 4) == 4, aspect % 4);
     int dm1 = ((aspect & 4) == 4) 2 : org.Length / 2, dm2 = org.Length / dm1;
     for (int i = 0; i < dm1; i++)
       for (int j = 0; j < dm2; j++)
         s += tgt[i, j].ToString() + ((j == dm2 - 1)
"\r\n" : "");
      s +=
"\r\n";
  }
  MessageBox.Show(s);
}


 

the routine Aspects need the dim parameter since it cannot be obtained inside the routine.

I split up the transpositions and the reflection in this routine because of the natural split of these factors in higher dimension where there are n! transpositions and 2^n reflections resulting in n!2^n aspectial variants





Re: Visual C# General Rotating Two Dimensional Arrays

Roland Sommer

And another one:

  public class Program< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

  {

    static void Main(string[] args)

    {

      TestRotation(new int[3, 3] { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 } });

      Console.WriteLine();

      TestRotation(new int[2, 3] { { 0, 1, 2 }, { 3, 4, 5 } });

    }

 

    public static void TestRotation(int[,] matrix)

    {

      Console.WriteLine("the original matrix:");

      PrintMatrix(matrix);

      Console.WriteLine();

      Console.WriteLine("the right rotated matrix:");

      PrintMatrix(RotateRight(matrix));

      Console.WriteLine();

      Console.WriteLine("the left rotated matrix:");

      PrintMatrix(RotateLeft(matrix));

    }

 

    public static void PrintMatrix(int[,] matrix)

    {

      int lengthX = matrix.GetLength(1);

      int lengthY = matrix.GetLength(0);

      for (int y = 0; y < lengthY; y++)

      {

        for (int x = 0; x < lengthX; x++)

          Console.Write(matrix[y, x]);

        Console.WriteLine();

      }

    }

 

    public static int[,] RotateRight(int[,] matrix)

    {

      int lengthY = matrix.GetLength(0);

      int lengthX = matrix.GetLength(1);

      int[,] result = new int[lengthX, lengthY];

      for (int y = 0; y < lengthY; y++)

        for (int x = 0; x < lengthX; x++)

          result[x, y] = matrix[lengthY - 1 - y, x];

      return result;

    }

 

    public static int[,] RotateLeft(int[,] matrix)

    {

      int lengthY = matrix.GetLength(0);

      int lengthX = matrix.GetLength(1);

      int[,] result = new int[lengthX, lengthY];

      for (int y = 0; y < lengthY; y++)

        for (int x = 0; x < lengthX; x++)

          result[x, y] = matrix[y, lengthX - 1 - x];

      return result;

    }

  }

 

Damn, how to post a piece of source with syntax highlighting and correct formatting

edit: changed formatting, see below ...





Re: Visual C# General Rotating Two Dimensional Arrays

A. de Winkel

Don't know of the performance, but a jagged array eliminates the extra parameter. The following I easily whipped up based on the previous listed:


int[][] Aspects(int[][] org, bool trans, int reflec)
{
  int dim = org[0].Length;
  int dm1 = (trans) dim : org.Length,
      dm2 = (trans) org.Length : dim;
  bool xref = (reflec & 1) == 1, yref = (reflec & 2) == 2;
  int[][] tgt = new int[dm1][];
  for (int i = 0; i < dm1; i++)
  {
     tgt[ i ] =
new int[dm2];
     for (int j = 0; j < dm2; j++)
     if (trans)
         tgt[ i ][ j ] = org[(xref) dm2 - 1 - j : j]
                               [(yref) dm1 - 1 - i : i];
    else

         tgt[ i ][ j ] = org[(xref) dm1 - 1 - i : i]
                               [(yref) dm2 - 1 - j : j];
  }
  return tgt;
}
void TestAspects()
{
  int[][] org = { new int[] { 1, 2 }, new int[] { 2, 3 }, new int[] { 4, 5 } };
  string s = "";
  for (int aspect = 0; aspect < 8; aspect++)
  {
     s +=
"Aspect " + aspect.ToString() + "\r\n";
     int[][] tgt = Aspects(org, (aspect & 4) == 4, aspect % 4);
     int dm1 = tgt.Length, dm2 = tgt[0].Length;
     for (int i = 0; i < dm1; i++)
        for (int j = 0; j < dm2; j++)
           s += tgt[ i ][j].ToString() + ((j == dm2 - 1)
"\r\n" : "");
           s +=
"\r\n";
  }
  MessageBox.Show(s);
}

 

With a jagged array the dimensions can be estimated, I reckon with Generics it is possible to estimate the Rank and make the routine for all dimensions, but this is another discussion.

 

note: just edited codetags onto this, need to say though that the preview doesn't show this and [ i ] is lamped out in code tags!





Re: Visual C# General Rotating Two Dimensional Arrays

TilakGopi

Damn, how to post a piece of source with syntax highlighting and correct formatting

Hi , copy the source from IDE to MSWord first, and from there copy to forum window.U'll have indentation,colored text.

 

Thanx,

Ch.T.Gopi Kumar.






Re: Visual C# General Rotating Two Dimensional Arrays

Matthew Watson

Or (the forum way), use the "code" tags.

In the example below, replace the "<" and ">" brackets with "[" and "]" brackets when posting.

<code language="csharp">
... Your code goes here
</code>






Re: Visual C# General Rotating Two Dimensional Arrays

Roland Sommer

Thx a lot TilakGopi and Matthew!

Quoting other posts, I recognized the [Code] tag a while ago.
Unfortunately in the quote the tag showed [Code language=C#] which didn't work.

:-)
now, that I know better ...

Code-Tag:



public string RolandSays()
{
return "thx a lot for clarifying that one!";
}

Word-workaround:

public string RolandSays()

{

return "thx a lot for clarifying that one!";

}