Rotation de matrice? [Algo] - Algo - Programmation
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 |
C'est une question d'algorithme qui n'a pas grand chose à voir avec le langage C...
-> forum 'Algo'
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...
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... |
Il doit tout juste commencer la programmation, vu la question...ta remarque est franchement stupide.
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... |
Super sympa, merci!
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 ?
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
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 |
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...
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
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...
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
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...
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 ?
Marsh Posté le 07-02-2005 à 12:08:14
vttman2 a écrit : Dans ce cas |
Bravo, tu viens d'écraser la moitié de tes données...
Marsh Posté le 07-02-2005 à 12:09:14
(même plus, d'ailleurs...)
Marsh Posté le 07-02-2005 à 12:14:41
skeye a écrit : (même plus, d'ailleurs...) |
il a écrasé toute ses données et a tout remplacé par la donnée situées en [1,1]
(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
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] |
euh...non.
Masklinn a écrit : |
pas en algo...
Marsh Posté le 07-02-2005 à 12:18:22
skeye a écrit : euh...non. |
ah merde j'avais pas vu le déroulement de l'algo, my bad, chuis un moisi des yeux
Marsh Posté le 07-02-2005 à 12:23:31
Ouais effectivement on efface des données de cette facon...
Masklinn > sur place...
Marsh Posté le 07-02-2005 à 12:30:45
Ryu Braska a écrit : Ouais effectivement on efface des données de cette facon... |
Ben t'as juste à déterminer le nombre de valeurs à stocker temporairement à chaque instant
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 |
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.
Marsh Posté le 07-02-2005 à 13:14:21
skeye a écrit : Bravo, tu viens d'écraser la moitié de tes données... |
Je suis en forme aujourd'hui, ça se voit !
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 ...
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 |
Pour une matrice 4x4 :
1 2 x x |
Pour une matrice 5x5 :
1 2 3 x x |
Un exemple avec une matrice 2x2 :
a b |
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 |
Mais bon, dupliquer la matrice pour faire cette rotation est vachement plus simple !
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" :
|
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
|
Et rebelote.
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. |
Pas réellement, voilà le détail pour une matrice 3x3 :
a b c |
Je fais la rotation de l'élément a, tout en sauvegardant l'élément c.
a b a |
Donc l'élément c prend la place de l'élément i.
a b a |
L'élément i prend la place de l'élément g.
a b a |
Et enfin l'élément g prend la place du premier élément.
g b a |
Il faut faire de même avec les éléments b, f, h et d.
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 ?
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).
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 ? |
Moi j'ai 25 lignes de code. La rotation est faite directement sur la liste des paramètres (normalement appelée "argv" ).
Le tout fonctionne bien quelque soit la taille de la matrice 2x2 ou 16x16 (par exemple mais la ligne de commande devient grande ).
Code :
|
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) ?
Marsh Posté le 08-02-2005 à 19:37:09
Code :
|
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
Marsh Posté le 09-02-2005 à 13:24:12
vttman2 a écrit : |
Aïe... Je crains le pire.
vttman2 a écrit : |
Mes craintes étaient fondées. C'est quoi, cette immondice vomitive ?
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 ;-)
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...
Marsh Posté le 09-02-2005 à 13:41:56
vttman2 a écrit : C pas sympa ça ... |
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 , mais dans la cat "algo", ça fait pas bon genre.
Ca mériterait un coup de pelle à clous. Je t'en fais grâce.
EDIT : le VBscrap, je ne pratique pas non plus, mais c'est pas une raison, on n'est pas vendredi
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 !
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.
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