2010-07-19 99 views
5

¿Cómo puedo rotar una matriz rectangular 2D de enteros que tiene un número impar de filas de 45 grados?Rotar matriz 2D en 45 grados

así que algo como

int[] myArray = new int[,] 
{ 
    {1, 0 ,1}, 
    {0, 1 ,0}, 
    {0, 0 ,0}, 
} 

en

int[] rotatedArray = new int[,] 
{ 
    {0, 1 ,0}, 
    {0, 1 ,1}, 
    {0, 0 ,0}, 
} 

de cualquier dimensión (3x3, 5x5, 7x7, etc.). Por esta fórmula http://yfrog.com/n6matrix45p

5x5

0 0 0 0 0 
2 0 0 0 0 
1 1 1 1 1 
0 0 0 0 0 
0 0 0 0 0 

en

1 2 0 0 0 
0 1 0 0 0 
0 0 1 0 0 
0 0 0 1 0 
0 0 0 0 1 

5x5

0 0 0 3 0 
0 0 0 3 0 
0 0 0 3 0 
0 0 0 3 0 
0 0 0 3 0 

en

0 0 0 0 0 
0 0 0 0 3 
0 0 0 3 0 
0 0 3 3 0 
0 3 0 0 0 

Respuesta

1

Este es un código escrito por mí y un amigo que resuelve esto:

public static class ArrayExtensions 
{ 
    public static Point RoundIndexToPoint(int index, int radius) 
    { 
     if (radius == 0) 
      return new Point(0, 0); 
     Point result = new Point(-radius, -radius); 

     while (index < 0) index += radius * 8; 
     index = index % (radius * 8); 

     int edgeLen = radius * 2; 

     if (index < edgeLen) 
     { 
      result.X += index; 
     } 
     else if ((index -= edgeLen) < edgeLen) 
     { 
      result.X = radius; 
      result.Y += index; 
     } 
     else if ((index -= edgeLen) < edgeLen) 
     { 
      result.X = radius - index; 
      result.Y = radius; 
     } 
     else if ((index -= edgeLen) < edgeLen) 
     { 
      result.Y = radius - index; 
     } 

     return result; 
    } 

    public static T[,] Rotate45<T>(this T[,] array) 
    { 
     int dim = Math.Max(array.GetLength(0), array.GetLength(0)); 

     T[,] result = new T[dim, dim]; 

     Point center = new Point((result.GetLength(0) - 1)/2, (result.GetLength(1) - 1)/2); 
     Point center2 = new Point((array.GetLength(0) - 1)/2, (array.GetLength(1) - 1)/2); 
     for (int r = 0; r <= (dim - 1)/2; r++) 
     { 
      for (int i = 0; i <= r * 8; i++) 
      { 
       Point source = RoundIndexToPoint(i, r); 
       Point target = RoundIndexToPoint(i + r, r); 

       if (!(center2.X + source.X < 0 || center2.Y + source.Y < 0 || center2.X + source.X >= array.GetLength(0) || center2.Y + source.Y >= array.GetLength(1))) 
        result[center.X + target.X, center.Y + target.Y] = array[center2.X + source.X, center2.Y + source.Y]; 
      } 
     } 
     return result; 
    }  
} 

0

Usted puede tratar de esta biblioteca:

Math.NET Project para las operaciones de matrices ... http://numerics.mathdotnet.com/

Este código parece ser útil también:

http://www.drunkenhyena.com/cgi-bin/view_net_article.pl?chapter=2;article=28#Rotation

No se olvide de la Espacios de nombres y clases administrados y no administrados de DirectX. Lotes y muchas cosas buenas para verificar.

Por ejemplo:

Matrix..::.Rotate Method (Single, MatrixOrder)

+0

esas matrices son solamente 4x4 o 3x3, voy a tratar math.net, pero me temo que esta rotación es demasiado específica – Kikaimaru

+4

Estas son matrices de rotación para transformaciones. Una cosa completamente diferente. – Cloudanger

0

Creo que tenemos estas reglas:

  1. imaginar la matriz como un conjunto de "marcos o cajas sin centros" dentro de otras como "Ruso muñecas ".

  2. Los elementos en el centro de un lado (arriba/izquierda/derecha/abajo) se mueven hacia la esquina más cercana en el sentido de las agujas del reloj.

  3. Las esquinas se mueven hacia el siguiente centro en el sentido de las agujas del reloj.

  4. Los elementos que no son esquinas ni centros se mueven al siguiente punto (en el sentido de las agujas del reloj) que está a la misma distancia de una esquina como lo están actualmente.

He comenzado a escribir algunos códigos, pero no creo que sea trivial y no he tenido tiempo de probar.

Cuestiones relacionadas