[Algo] Rotation de matrice?

Rotation de matrice? [Algo] - Algo - Programmation

Marsh Posté le 07-02-2005 à 00:40:02    

Admettons que j'ai une matrice de 4x4 à laquelle je veux faire une rotation de 90 degrés vers la droite
 
1  2  3  4
5  6  7  8
9  10 11 12
13 14 15 16
 
qui deviendrait alors
 
13 9 5 1
14 10 6 2
15 11 7 3
16 12 8 4
 
Est-ce possible de faire l'opération sans utiliser une matrice intermediaire?


Message édité par Ryu Braska le 07-02-2005 à 11:31:33
Reply

Marsh Posté le 07-02-2005 à 00:40:02   

Reply

Marsh Posté le 07-02-2005 à 08:28:42    

Ryu Braska a écrit :

Admettons que j'ai une matrice de 4x4 à laquelle je veux faire une rotation de 90 degrés vers la droite
 
1  2  3  4
5  6  7  8
9  10 11 12
13 14 15 16
 
qui deviendrait alors
 
13 9 5 1
14 10 6 2
15 11 7 3
16 12 8 4
 
Est-ce possible de faire l'opération sans utiliser une matrice intermediaire?


C'est une question d'algorithme qui n'a pas grand chose à voir avec le langage C...  
 
-> forum 'Algo'


Message édité par Emmanuel Delahaye le 07-02-2005 à 08:29:45

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 07-02-2005 à 09:35:40    

oui c'est une question d'algo pas tès compliquée franchement...
 
si tu n'es pas capable de faire ça, tu ne seras jms un bon programmeur...

Reply

Marsh Posté le 07-02-2005 à 09:37:16    

moi23372 a écrit :

oui c'est une question d'algo pas tès compliquée franchement...
 
si tu n'es pas capable de faire ça, tu ne seras jms un bon programmeur...


[:kiki]
Il doit tout juste commencer la programmation, vu la question...ta remarque est franchement stupide.


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 07-02-2005 à 11:32:00    

moi23372 a écrit :

oui c'est une question d'algo pas tès compliquée franchement...
 
si tu n'es pas capable de faire ça, tu ne seras jms un bon programmeur...


 
Super sympa, merci!  :jap:

Reply

Marsh Posté le 07-02-2005 à 11:45:28    

Tu vois comment faire, utilisation  
de tableau par exemple ...
 
Les données de tes matrices sont stockées ou ?
 
Tu utilises quel langage ?

Reply

Marsh Posté le 07-02-2005 à 11:47:29    

Du C.... les données sont dans un tableau à 2 dimensions... je veux pouvoir les "tourner" sans effacer des données et sans utiliser un tableau intermediaire  :pt1cable:

Reply

Marsh Posté le 07-02-2005 à 11:49:01    

Ryu Braska a écrit :

Du C.... les données sont dans un tableau à 2 dimensions... je veux pouvoir les "tourner" sans effacer des données et sans utiliser un tableau intermediaire  :pt1cable:


Ca doit être faisable...Tu prends la première valeur, tu calcules sa nouvelle position, tu stockes la valeur qui s'y trouve, tu remplaces par la première valeur, et ainsi de suite jusqu'à avoir tout fait...[:ddr555]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 07-02-2005 à 11:50:57    

Je sais bien mais je me suis installé devant une feuille de papier, mais je ne sais pas pourquoi j'arrive pas à trouver une solution simple et pourtant j'ai l'impression que c'est hyper simple. C'est pourquoi je demandais pour voir si quelqu'un ne connaitrait pas une belle solution toute simple ;)

Reply

Marsh Posté le 07-02-2005 à 11:51:54    

Bah t'as plus qu'à trouver la formule pour calculer la nouvelle position à-partir de l'ancienne, c'est pas bien complexe...;)


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 07-02-2005 à 11:51:54   

Reply

Marsh Posté le 07-02-2005 à 11:54:22    

Bah [i,j] -> [j,max-i] mais c'est la boucle pour tout faire efficacement sans perdre de données qui m'échappe

Reply

Marsh Posté le 07-02-2005 à 11:55:30    

Ryu Braska a écrit :

Bah [i,j] -> [j,max-i] mais c'est la boucle pour tout faire efficacement sans perdre de données qui m'échappe


Commence à l'écrire, tu te rendras compte tout seul des variables qu'il te faut...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 07-02-2005 à 12:07:10    

Dans ce cas  
=>  
pour i de 1 à Max
  pour j de 1 à max
    Bah [i,j] -> [j,max-i]
  fpourj
fpouri
 
A transcrire en c ... non ?

Reply

Marsh Posté le 07-02-2005 à 12:08:14    

vttman2 a écrit :

Dans ce cas  
=>  
pour i de 1 à Max
  pour j de 1 à max
    Bah [i,j] -> [j,max-i]
  fpourj
fpouri
 
A transcrire en c ... non ?


 
Bravo, tu viens d'écraser la moitié de tes données...[:dawa]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 07-02-2005 à 12:09:14    

(même plus, d'ailleurs...[:ddr555])


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 07-02-2005 à 12:14:41    

skeye a écrit :

(même plus, d'ailleurs...[:ddr555])


il a écrasé toute ses données et a tout remplacé par la donnée situées en [1,1] [:aloy]
(j'ajouterais qu'on commence habituellement un tableau à l'indice 0)
 
Ryu > tu veux faire une rotation "en place" (càd donner une matrice en entrée et retrouver la même en matrice tournée) ou une rotation "copie" (càd avoir 2 matrices en sortie, l'originelle et la matrice tournée)?
 
Pour une rotation en place, pense simplement au stockage temporaire de données et combien de données tu dois stocker à chaque instant T


Message édité par masklinn le 07-02-2005 à 12:19:16

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 07-02-2005 à 12:16:21    

Masklinn a écrit :

il a écrasé toute ses données et a tout remplacé par la donnée situées en [1,1] [:aloy]


 
euh...non. :heink:
 

Masklinn a écrit :


(j'ajouterais qu'on commence habituellement un tableau à l'indice 0)


 
pas en algo...:o


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 07-02-2005 à 12:18:22    

skeye a écrit :

euh...non. :heink:


ah merde j'avais pas vu le déroulement de l'algo, my bad, chuis un moisi des yeux [:matleflou]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 07-02-2005 à 12:23:31    

Ouais effectivement on efface des données de cette facon...
 
Masklinn > sur place...

Reply

Marsh Posté le 07-02-2005 à 12:30:45    

Ryu Braska a écrit :

Ouais effectivement on efface des données de cette facon...
 
Masklinn > sur place...


Ben t'as juste à déterminer le nombre de valeurs à stocker temporairement à chaque instant [:cupra]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 07-02-2005 à 13:05:29    

Dans le cas simple d'une rotation de 90° dans le sens des aiguilles d'une montre et avec une matrice 3x3 :

a ? b
? * ?
c ? d

Si on traite le point a, on va se rendre compte qu'il va prendre la place du point b, qui va prendre à son tour la place du point c, ...
Voilà un peut la réflexion que j'aurais.


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 07-02-2005 à 13:14:21    

skeye a écrit :

Bravo, tu viens d'écraser la moitié de tes données...[:dawa]


 :ouch:
Je suis en forme aujourd'hui, ça se voit !
 :lol:

Reply

Marsh Posté le 07-02-2005 à 13:46:52    

Pourquoi ne pas simplement faire une fonction swap, toute conne et l'appliquer a tous les elements de la matrice? Si t'as une matrice 4*4 tu peux le faire directement, si c'est pour une matrice n*n tu fait ca en boucle ...


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 07-02-2005 à 18:36:06    

Chronoklazm a écrit :

Pourquoi ne pas simplement faire une fonction swap, toute conne et l'appliquer a tous les elements de la matrice? Si t'as une matrice 4*4 tu peux le faire directement, si c'est pour une matrice n*n tu fait ca en boucle ...

Le problème est que tu ne peux pas "swapper" deux éléments simplement, en fait il fait faire tourner quatre éléments à la fois.
 
Voici l'approche que j'ai utilisé :
 
Lorsque je rote un élément je fais aussi roté l'élément sur lequel j'arrive, je n'ai donc pas besoin de travailler sur la totalité de la matrice pour réaliser la rotation puisque chaque rotation déplace 4 points.
 
Pour une matrice 3x3 voilà les points de départ que je vais utiliser :

1 2 x
x o x
x x x


 
Pour une matrice 4x4 :

1 2 x x
3 4 x x
x x x x
x x x x


 
Pour une matrice 5x5 :

1 2 3 x x
4 5 6 x x
x x o x x
x x x x x
x x x x x


 
Un exemple avec une matrice 2x2 :

a b
c d


 
Il faut déterminer le centre de la rotation, dans le cas d'une matrice 2x2, le centre est (0.5,0.5).
 
Pour chaque point à faire tourner, il faut déterminer son décalage par rapport au point de rotation. Dans le cas d'une matrice 2x2, il y a un seul point à faire tourner (4x). À chaque rotation, on enregistre la valeur de l'élément sur lequel on se trouve et on écrit la valeur de l'élément dont on vient.
 
Les coordonnées se calculent de la façon suivante (pour une matrice 2x2) :
 - Décalage du point de départ de la rotation (a) avec le centre de rotation : Dx=-0,5 et Dy=-0,5.
 - On obtient les coordonnées du premier point (b) :
  => bx = (rx-Dy)
  => by = (ry+Dx)
 - Pour le deuxième point (c) :
  => cx = (rx-Dx)
  => cy = (ry-Dy)
 - Pour le troisième point (d) :
  => dx = (rx+Dy)
  => dy = (ry-Dx)
 - Pour le quatrième point, on en connait déjà les coordonnées !
 
Cette méthode s'applique a n'importe quelle taille de matrice.
 
Je ne sais pas si j'ai été clair, voilà un exemple du petit programme que j'ai écrit :

/home/darkoli/hfr > ./rotation_matrice a b c d e f g h i j k l m n o p q r s t u v w x y
La matrice est de taille : 5x5.
 
a b c d e
f g h i j
k l m n o
p q r s t
u v w x y
 
u p k f a
v q l g b
w r m h c
x s n i d
y t o j e

Mais bon, dupliquer la matrice pour faire cette rotation est vachement plus simple ! :D


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 07-02-2005 à 18:38:52    

Ouaip, en dupliquant c'est plusse mieux...

Reply

Marsh Posté le 07-02-2005 à 19:50:10    

Plus simple oui mais pas mieux ;)

Reply

Marsh Posté le 07-02-2005 à 21:01:02    

C'est sympa, ton approche "point de pivot au centre" et je me concentre sur ce qu'il y a au-dessus à gauche.
 
J'avais pensé à ceci :
 
Tu attaques la matrice par le "périmètre extérieur" :


1  2  3  4
5  x  x  8
9  x  x  12
13 14 15 16


Et tu appliques la "4 swap points exploding technique" que tu as décrite à la rangée du dessus (donc tout le périmètre extérieur va subir la rotation).
 
Ensuite, tu passes au périmètre intérieur suivant


x  x  x  x
x  6  7  x
x  10 11 x
x  x  x  x


Et rebelote.


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 07-02-2005 à 22:19:28    

sircam a écrit :

C'est sympa, ton approche "point de pivot au centre" et je me concentre sur ce qu'il y a au-dessus à gauche.
 
J'avais pensé à ceci :
 
Tu attaques la matrice par le "périmètre extérieur" :


Pas réellement, voilà le détail pour une matrice 3x3 :

a b c
d e f
g h i

Je fais la rotation de l'élément a, tout en sauvegardant l'élément c.

a b a
d e f
g h i

Donc l'élément c prend la place de l'élément i.

a b a
d e f
g h c

L'élément i prend la place de l'élément g.

a b a
d e f
i h c

Et enfin l'élément g prend la place du premier élément.

g b a
d e f
i h c


Il faut faire de même avec les éléments b, f, h et d. :D


Message édité par darkoli le 07-02-2005 à 22:20:06

---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 08-02-2005 à 09:17:00    

Enfin soit, ça revient +/- au même à un chouia près, problème résolu.
 
D'autres questions ? :D


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 08-02-2005 à 09:28:47    

Darkoli, dans ta méthode, il y a combien de lignes de code pour faire la rotation ?
 
Parce qu'avec la méthode sircam (celle qui m'a paru la plus évidente intuitivement), j'ai 9 lignes de code (2 for, 2 accolades, et 5 lignes d'affectations pour transvaser les valeurs).

Reply

Marsh Posté le 08-02-2005 à 19:29:42    

Lam's a écrit :

Darkoli, dans ta méthode, il y a combien de lignes de code pour faire la rotation ?
 
Parce qu'avec la méthode sircam (celle qui m'a paru la plus évidente intuitivement), j'ai 9 lignes de code (2 for, 2 accolades, et 5 lignes d'affectations pour transvaser les valeurs).


Moi j'ai 25 lignes de code. La rotation est faite directement sur la liste des paramètres (normalement appelée "argv" :D).
Le tout fonctionne bien quelque soit la taille de la matrice 2x2 ou 16x16 (par exemple mais la ligne de commande devient grande :D).

Code :
  1. lzr=(l+1)>>1;
  2. hzr=l>>1;
  3. m=l-1;
  4. for (j=0;j<hzr;j++)
  5. {
  6.   dy=(j<<1)-m;
  7.   for (i=0;i<lzr;i++)
  8.    {
  9.     dx=(i<<1)-m;
  10.     x=i;
  11.     y=j;
  12.     t2=parametres[(y*l)+x+1];
  13.     for (k=0;k<4;k++)
  14.      {
  15.       td=dx;
  16.       dx=-dy;
  17.       dy=td;
  18.       x=(m+dx)>>1;
  19.       y=(m+dy)>>1;
  20.       t1=parametres[(y*l)+x+1];
  21.       parametres[(y*l)+x+1]=t2;
  22.       t2=t1;
  23.      }
  24.    }
  25. }

En fait je ne suis pas certain d'avoir bien compris la méthode de sircam. En utilisant par exemple le périmètre extérieur, chaque élément va être déplacé 4 fois (pour une matrice 4x4) ?


Message édité par darkoli le 08-02-2005 à 19:33:38

---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 08-02-2005 à 19:37:09    

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #define max 4
  4. int tab[max+1][max+1];
  5. int main()
  6. {
  7.   size_t i,j;
  8.   for (i=0; i<=max; ++i)
  9.      for (j=0; j<=max; ++j)
  10.        tab[j][i] = i*(max+1)+j+1;
  11.   for (i=0; i<=max; ++i)
  12.   {
  13.      for (j=0; j<=max; ++j)
  14.        printf("%2d ", tab[j][i]);
  15.      printf ("\n" );
  16.   }
  17.  
  18.   printf ("\nApres:\n" );
  19.   for (j=0; j<max-1; ++j)
  20.     {
  21.       for (i=j; i<max-j; ++i)
  22.          {
  23.            int temp  =tab[i][j] ;
  24.            tab[i][j] = tab[max-j][i];
  25.            tab[max-j][i] = tab[max-i][max-j];
  26.            tab[max-i][max-j] =tab[j][max-i];
  27.            tab[j][max-i] = temp;
  28.  }
  29.     }
  30.   for (i=0; i<=max; ++i)
  31.   {
  32.      for (j=0; j<=max; ++j)
  33.        printf("%2d ", tab[j][i]);
  34.      printf ("\n" );
  35.   }
  36.   return 0;
  37. }


Message édité par Lam's le 08-02-2005 à 19:43:45
Reply

Marsh Posté le 09-02-2005 à 12:20:27    

En retard  ;) Méthode Similaire Sircam donc ...
Pour ma part, je propose un vbscript ...
J'effectue une rotation sur le "carré" de valeurs extérieur (dim 5)
1 2 3 4 5 10 15 20 25 24 23 33 21 16 11 6 1
puis sur les "carrés" plus petit (ici dim 3)
7 8 9 14 19 18 17 12 7
 
=>
 
Dim i ,tab(5,5)
 
tab(1,1)=1  
tab(1,2)=2  
tab(1,3)=3  
tab(1,4)=4  
tab(1,5)=5  
tab(2,1)=6  
tab(2,2)=7  
tab(2,3)=8  
tab(2,4)=9  
tab(2,5)=10  
tab(3,1)=11  
tab(3,2)=12  
tab(3,3)=13  
tab(3,4)=14  
tab(3,5)=15  
tab(4,1)=16  
tab(4,2)=17  
tab(4,3)=18  
tab(4,4)=19  
tab(4,5)=20  
tab(5,1)=21  
tab(5,2)=22  
tab(5,3)=23  
tab(5,4)=24  
tab(5,5)=25  
 
max=6
for i = 1 to 2
for j = i to Max-i-1
  tmp = tab(j,max-i)
  tab(j    , max-i) = tab(i    , j)  
  tmp1 = tab(max-i, max-j)
  tab(max-i, max-j) = tmp
  tmp = tab(max-j, i    )  
  tab(max-j, i    ) = tmp1  
  tab(i    , j    ) = tmp
next
next
 
Remarque :
=>
Marche pour toute matrice  
La variable Max est le nombre de colonne + 1 (ici 5+1)
 
 
Verif ligne par ligne
=>

 
for i = 1 to (Max -1)
MsgBox  tab(i,1) & " "  & tab(i,2) & " " & tab(i,3) & " " & tab(i,4) & " " & tab(i,5)  
next


Message édité par vttman2 le 09-02-2005 à 13:32:04
Reply

Marsh Posté le 09-02-2005 à 13:24:12    

vttman2 a écrit :


Pour ma part, je propose un vbscript ...


Aïe... Je crains le pire.

vttman2 a écrit :


Dim i ,tab(5,5)
 
tab(1,1)=1  
tab(1,2)=2  
tab(1,3)=3  
tab(1,4)=4  
tab(1,5)=5  
tab(2,1)=6  
tab(2,2)=7  
tab(2,3)=8  
tab(2,4)=9  
tab(2,5)=10  
tab(3,1)=11  
tab(3,2)=12  
tab(3,3)=13  
tab(3,4)=14  
tab(3,5)=15  
tab(4,1)=16  
tab(4,2)=17  
tab(4,3)=18  
tab(4,4)=19  
tab(4,5)=20  
tab(5,1)=21  
tab(5,2)=22  
tab(5,3)=23  
tab(5,4)=24  
tab(5,5)=25  


[:kiki] Mes craintes étaient fondées. C'est quoi, cette immondice vomitive ? [:austiniste]


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 09-02-2005 à 13:34:35    

C pas sympa ça ...
ça a pas de style (je reconnais)
mais ça fonctionne !
Cela dit le vbscript je pratique pas ;-)
 

Reply

Marsh Posté le 09-02-2005 à 13:39:50    

Boah, t'as qu'à faire comme dans les lignes 12 à 14 de mon bout de code...
 

Reply

Marsh Posté le 09-02-2005 à 13:41:56    

vttman2 a écrit :

C pas sympa ça ...
ça a pas de style (je reconnais)
mais ça fonctionne !
Cela dit le vbscript je pratique pas ;-)


Oh dis, désolé, ne le prends pas mal, t'es sans doute un gars bien, c'est rien de perso ni un jugement de valeur, mais ça... ça... ce truc là... C'est dégueulasse !
 
On serait dans la cat "VB" que ça ne choquerait personne  :p, mais dans la cat "algo", ça fait pas bon genre.
 
Ca mériterait un coup de pelle à clous. Je t'en fais grâce.  :D
 
EDIT : le VBscrap, je ne pratique pas non plus, mais c'est pas une raison, on n'est pas vendredi :o


Message édité par sircam le 09-02-2005 à 13:42:39

---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 09-02-2005 à 13:43:55    

C sûr ...
Mais bon là je m'étais un peu focalisé sur le pb
et pas sur l'entrée des données
 
Je le referai plus M'sieur !
 

Reply

Marsh Posté le 09-02-2005 à 13:44:45    

:ange:


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 05-03-2005 à 16:12:37    

Juste un ptit truc, je pense qu'on peut un tout petit peu améliorer la méthode de darkoli en faisant la rotation dans l'autre sens :  
 
a b c
d e f
g h i
 
on sauvegarde a, on met g dans a, i dans g, c dans i puis a dans c : on n'a utilisé qu'une seule affectation de variable.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed