Newsgroup: it.comp.lang.c
Titolo: Rotazione matrice.

Per un programmino che sto sviluppando devo ruotare una matrice di 4
elementi di 90 gradi sia a dx che a sx: per esempio con la rotazione
verso dx la matrice diventera' una cosa del genere:
a a a a
b b b b
c c c c
d d d d
diventera'
d c b a
d c b a
d c b a
d c b a
Dovrei esserci arrivato con queste istruzioni, dove copio i dati in una
matrice temporanea che poi viene ricopiata ruotata nell'originale:
// Rotazione a SX
for(i=0;i<4;i++)
   for(j=0;j<4;j++)
      tmp[i][j] = mat[j][i];
// Rotazione a DX
for(i=0;i<4;i++)
   for(j=0;j<4;j++)
      tmp[i][j] = mat[3-j][i];
E' l'unico modo questo o esiste qualcosa di piu' efficiente?
Il fatto e' che devo fare 4 cicli for ogni volta...
2 per copiare nella temporanea.
2 per riscrivere nella matrice...
Avete qualche idea migliore?
--
Napolux
http://napolux.altervista.org
[Powered by BloggIT 1.01]

 d c b a
Le matrici che devi ruotare hanno proprio questa forma particolare,
cioe` hanno un unico valore su ciascuna riga?
Se si`, allora possiamo notare due fatti importantissimi
  - Nella rotazione in senso antiorario, le due matrici sono semplicemente
    l'una la trasposta dell'altra
  - Nella rotazione in senso orario, le due matrici sono trasposte, ma
    rispetto alla diagonale secondaria:
Quindi, per la rotazione antioraria (a sx), con N = ordine della matrice,
fai:
for ( j = 0; j < N - 1; j++ )
     for ( i = j + 1; i < N; i++ ) {
         temp = mat[j][i];
         mat[j][i] = mat[i][j];
         mat[i][j] = temp;
     }
Mentre per la rotazione oraria (a dx) fai:
for ( j = 0; j < N - 1; j++ )
     for ( i = 0; i < N - j - 1; i++ ) {
         temp = mat[ N-j ][ N-i ];
         mat[ N-j ][ N-i ] = mat[i][j];
         mat[i][j] = temp;
     }
Spero di non aver commesso errori, cmq ricontrollandolo mi pare di no.
Se pero` la tua matrice non ha questa struttura particolare, allora
la prima idea che mi viene in mente e`:
  - invece di dichiarare mat staticamente lo dichiari come puntatore
    a puntatori;
  - quando devi compiere la rotazione, allochi spazio per un'altra
    matrice tmp, copi (facendo la rotazione) da mat alla nuova
    matrice, deallochi mat e fai "mat = tmp;" in modo che mat
    contenga sempre la matrice corretta. Cosi` ti eviti di dover
    ricopiare i dati da tmp a mat.
Saluti,
Marco

> Le matrici che devi ruotare hanno proprio questa forma particolare,
cioe` hanno un unico valore su ciascuna riga?
No, avranno valori casuali, ma comunque saranno sempre quadrate. Le ho
messe uguali per riga in modo che si capisse meglio il "movimento" che
devono fare.
Cmq usare i puntatori non e' una cosa fattibile nel mio caso, ci avevo
pensato anch'io.
Grazie dell'aiuto


    ricopiare i dati da tmp a mat.
naturalmente se vuoi fare una cosa veloce devi assolutamente
evitare di allocare e deallocare frenquentemente delle matrici...
Un modo efficiente di risolvere il problema e' questo, che non
richiede matrici di supporto, visto che gli scambi si fanno
in sito:
t=A[0][0];
A[0][0]=A[3][0]; A[3][0]=A[3][3]; A[3][3]=A[0][3]; A[0][3]=t;
t=A[0][1];
A[0][1]=A[2][0]; A[2][0]=A[3][2]; A[3][2]=A[1][3]; A[1][3]=t;
t=A[0][2];
A[0][2]=A[1][0]; A[1][0]=A[3][1]; A[3][1]=A[2][3]; A[2][3]=t;
t=A[1][1];
A[1][1]=A[2][1]; A[2][1]=A[2][2]; A[2][2]=A[1][2]; A[1][2]=t;
fine.
Se vuoi la rotazione nell'altra direzione le istruzioni
te le scrivi tu..
ciao,
g.

Non proprio codice pulito...
;)
Ma forse e' sempre meglio che fare tanti for...


 Non proprio codice pulito...
mi permetto di dissentire. Il codice e' pulitissimo.
Contiene solo assegnamenti.
La rotazione di 90 gradi identifica 4 gruppi indipendenti
di 4 elementi che ruotano ciclicamente.
Puoi farlo con 2 cicli for e forse il compilatore potrebbe essere in
grado di eliminarli dal codice automaticamente,
ma in questo caso essendo solo matrici 4x4 si puo' fare "a mano" come
ti ho mostrato,
ciao,
g.

 ha scritto nel messaggio 
news:1112854951.8...@l41g2000cwc.googlegroups.com...


 leggermente + efficente...modestia a parte. ;)
Potrebbe essere, ma purtroppo non potr' usare puntatori...
--
Napolux
http://napolux.altervista.org
[Powered by BloggIT 1.01]
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/