Seuls les membres ayant 30 points peuvent parler sur le chat.

Forum Casio - Vos tutoriels et astuces


Index du Forum » Vos tutoriels et astuces » Rotation d'une image autour d'un point (Basic)
DrakHors ligneRédacteurPoints: 1923 Défis: 38 Message

Rotation d'une image autour d'un point (Basic)

Posté le 30/06/2016 12:32

Bonjour, bonsoir, mes salutations.

Je voulais proposer, pour ceux que ça intéresserait, Un programme vous permettant d'obtenir vos images/objets dont les coordonnées des points sont contenues dans une liste après rotation autour d'un point.

Pour cela, nous allons utiliser les complexes et les radians.

Admettons que votre dessin soit contenu dans les listes 2 (X) et 3 (Y).
On va d'abord définir une liste (list 1) qui contient les affixes des points correspondant aux listes 2 et 3.

List 2+[b]i[/b]List 3→List 1
Dim list 1→Tθmax "On va utiliser la fonction Graph(X,Y)"


Il s'agit maintenant de faire tourner chaque point autour de l'origine grâce aux fonctions Arg et Abs (Argument et Module d'un complexe).
Pour ceux qui ne connaissent pas bien les complexes, rappelons qu'un complexe peut s'écrire (sous forme algébrique) sous la forme z = a + b i avec a et b des réels (et i tel que i²=-1)
La partie réelle d'un complexe définit l'abscisse du point et la partie imaginaire définit son ordonnée :
z = a + b [b]i[/b]
Rep z = a "Partie réelle de Z"
Imp z = b "Partie Imaginaire de Z"

L'argument d'un complexe traduit l'angle entre le vecteur unitaire des abscisses (u, par exemple) et la demi-droite [OZ) avec O l'origine du repère et Z le point d'affixe (=de coordonnées) z = a + b i. Le module de z traduit quant à lui la longueur OZ.

Bref, (re)passez la terminale S si vous ne comprenez rien.

C'est là que ça devient intéressant. Vous vous connaissez du cercle trigonométrique, cette merveille ?



Ce qui m'intéresse, c'est que dans ce cercle (de rayon 1), X = cos(t) et Y = sin(t) avec t l'angle sur l'image.
Avec les complexes, ça nous donne a = cos (arg z) et b = sin (arg z) avec arg z l'argument de z... Mais pas tout à fait. Le cercle trigonométrique est de rayon 1. On multiplie ces valeurs par le module (distance OZ) pour obtenir ce que l'on veut :
donc on a :
a = (module de z : )|z|*cos (arg z)
et b = |z| * sin(arg z)


Seulement, on souhaite faire tourner ce point d'affixe z. On va donc augmenter (ou diminuer) l'argument de z, c'est-à-dire l'angle entre l'axe des abscisses (le vecteur directeur u) et la demi-droite [OZ). Prenons une rotation de π radians, et z'=a' + i b' le nouvel affixe du point Z après rotation.
Alors :
a' = |z|*cos(π + arg z)
et b' = |z|*sin(π + arg z)

C'est bien beau tout ça, mais on va où ? Akwasasert ?

Ne paniquez pas. Nous y sommes. Ce code consistera donc à modifier tous les affixes de tous les points en les faisant tourner de θ radians. Mais il manque un détail : Cela ne fonctionne que pour les rotations autour de l'origine du repère. Nous allons donc définir au préalable un point de coordonnées (I , J) qui fera office de centre de rotation (en général le centre de l'image). En faisant l'opération List 1 - ( I + i J ), le centre de l'image coïncide avec l'origine. Voici donc comment tout cela se met en place :

Cliquez sur moi pour me dérouler
Cliquez sur moi pour m'enrouler

?→I
?→J
?→θ
List 2 - I + [b]i[/b](List 3 -J→List 1
Dim List 1→Tθmax
For 1→A To Tθmax
List 1[A→B
Abs (B)((cos (θ+Arg B) + [b]i[/b]sin (θ+Arg B→List 1[A
Next
List 1+I+[b]i[/b] J→List 1


Voici une idée de code. Bien sûr, les techniques peuvent varier et sont plus ou moins efficaces selon les situations.
Je vous renvoie sur ce Tutoriel de neuronix qui donne également une très bonne piste dans cette optique.

Mais comment s'en servir ?

J'ai conçu ce code pour mon futur programme de jeu en basic casio. Si vous avez un personnage portant une arme et donnant un coup avec, par exemple, il est évident que vous n'allez pas vous amuser à réécrire les trois (ou cinq, voire dix... soyons fous.) listes différentes pour un même objet qui ne fait que tourner. Pour une image avec peu de points, vous pouvez également créer des animations, pourquoi pas. Les possibilités sont multiples et ce code me permet d'approfondir l'utilisation des graphismes en basic.
Je l'ai donné un peu brut, c'est fait exprès. Vous pouvez vous le réapproprier, vous en inspirer ou l'employer tel quel. It's up to you, guys!


Nota bene : Vous pouvez rencontrer des soucis dès lors que votre point de coordonnées I, J coïncide avec l'un des points de votre dessin. La machine vous indiquera une erreur lors du calcul de l'argument d'un point d'affixe 0. Une astuce consisterait à employer une valeur de I ou de J très légèrement différente (de 0.1, par exemple) pour que le code fonctionne et que votre dessin semble bien tourner !

Fichier joint


Pages : 1, 2Suivante
LephenixnoirEn ligneAdministrateurPoints: 15513 Défis: 136 Message

Citer : Posté le 30/06/2016 12:55 | #


Si ta liste contient des complexes, la rotation d'angle x autour de 0 s'exprime par
R_x(z) = e^ix * z

La multiplication est automatiquement mappée sur la liste, donc si le centre est en 0 :
e^iX * List 1→List 1

Sinon, on la ramène en 0 par translation. Supposons que le centre soit (A, B) :
(A+iB) + e^iX * (List 1 - (A+iB))→List 1

Et voilà !
DrakHors ligneRédacteurPoints: 1923 Défis: 38 Message

Citer : Posté le 30/06/2016 13:38 | #


Effectivement, j'ai employé la forme trigonométrique dans mon code. La forme exponentielle semble bien plus efficace (je rage de ne pas y avoir pensé... Grrrmmmbblrgrgb...) et surtout plus courte.
J'ai l'impression d'avoir fait ça pour rien, ça m'énerve.
Eon the Dragon : version 1.2
Let's have a look!
Marre de ces RPGs qui t'imposent des classes, des compétences et des sorts ? Crée tes propres capacités sur Eon the Dragon ! Des monstres, des dragons et des combats aussi épiques que difficiles t'attendent !
Un RPG unique et immense t'attend ! Joue dès maintenant à Aventura, le Royaume Poudingue !
Vous aussi, soyez swag et rejoignez Planète Casio !
LephenixnoirEn ligneAdministrateurPoints: 15513 Défis: 136 Message

Citer : Posté le 30/06/2016 13:41 | #


Non, ce n'était pas pour rien. La dernière fois que j'ai fait un calcul de rotation en C j'ai utilisé la même méthode et j'ai employé atan2(). Le résultat était désastreux, mais maintenant que j'ai fait le cours sur les espaces vectoriels réels et les isométries, je me ferai plus avoir.

Ça fait de l'expérience et au moins le plaisir d'avoir réussi à le faire, quelle que soit la forme. C'est pas rien déjà !
NinestarsHors ligneMembrePoints: 2247 Défis: 22 Message

Citer : Posté le 01/07/2016 13:42 | #


En effet, la forme exponentielle simplifie grandement ce genre de tranformation.
Sinon une matrice de rotation fait aussi bien l'affaire, je ne sais pas lequel est le plus rapide
LephenixnoirEn ligneAdministrateurPoints: 15513 Défis: 136 Message

Citer : Posté le 01/07/2016 13:44 | #


En l'occurrence si la liste est en complexes il vaut mieux utiliser la forme exponentielle. Le produit matriciel n'est utilisable réellement en Basic, que si l'on dispose de matrices pour les coordonnées.
NinestarsHors ligneMembrePoints: 2247 Défis: 22 Message

Citer : Posté le 01/07/2016 13:48 | #


C'est vrai, mais ici l'espace de départ est R, il passe des réels aux complexes pour revenir aux réels.
Non pas forcement besoin d'utiliser les matrices Mat, il faut utiliser directement la projection sur x et sur y on obtient 2 équations
LephenixnoirEn ligneAdministrateurPoints: 15513 Défis: 136 Message

Citer : Posté le 01/07/2016 14:15 | #


Bien sûr, mais au final c'est strictement pareil puisque la matrice de rotation est le complexe associé (du point de vue d'un isomorphisme classique entre Z et M_2(R)). Faire le produit revient au même, mais l'idée c'est toujours d'en faire faire le plus implicitement à l'interpréteur. Ici on évite de séparer les coordonnées, tandis que l'approche vectorielle nous oblige à récupérer indépendamment les parties, ce qui sera fatalement plus lent.
NinestarsHors ligneMembrePoints: 2247 Défis: 22 Message

Citer : Posté le 01/07/2016 16:58 | #


Lephenixnoir a écrit :
ce qui sera fatalement plus lent
Il faut éviter les raccourcis comme ceux là même s'ils sont assez tentant.

La matrice de rotation ((cos -sin)(sin cos)) va bien plus vite. Faire la rotation de 6 points va 25% plus vite et faire la rotation avec 16 points va 35% plus vite.
LephenixnoirEn ligneAdministrateurPoints: 15513 Défis: 136 Message

Citer : Posté le 01/07/2016 16:59 | #


Comment as-tu implémenté ça ?
NinestarsHors ligneMembrePoints: 2247 Défis: 22 Message

Citer : Posté le 01/07/2016 17:04 | #


D'un coté
{...->List 1
{...->List 2
List 1+iList 2->List 3
e^(9i)*List 3->List 3
Rep List 3->List 4
Imp List 3->List 5

et de l'autre
{...->List 1
{...->List 2
cos 9*List 1-sin 9*List 2->List 3
sin 9*List 1+cos 9*List 2->List 4



Ajouté le 01/07/2016 à 17:05 :
Je fais tourner ce code X fois et je mesure le temps
LephenixnoirEn ligneAdministrateurPoints: 15513 Défis: 136 Message

Citer : Posté le 01/07/2016 17:09 | #


Je partais du principe que l'on disposait d'une seule liste avec des valeurs complexes et que l'on générait en sortie une autre liste à valeurs complexes, comme le font les programmes réels. Du coup, je soulignais que l'on devait passer par les parties réelles et imaginaires ([l'approche vectorielle nous oblige à récupérer indépendamment les parties]).

Que donnent les performances dans ce cas-là ? Car de ces deux codes, le premier me semble « de vue » plus efficace :
e^(9i)*List 1→List 2

cos 9*(ReP List1)-sin 9*(ImP List 1)
+i(sin 9*(ReP List1)+cos 9*(ImP List1))→List 2

NinestarsHors ligneMembrePoints: 2247 Défis: 22 Message

Citer : Posté le 01/07/2016 17:25 | #


Lephenixnoir a écrit :
comme le font les programmes réel
C'est à dire ? Je n'ai j'amais vu l'utilisation des complexes dans ce genre d'application.
l'approche vectorielle nous oblige à récupérer indépendamment les parties
c'est bien "ces" parties qui sont utiles justement

Enfin il faut être maso pour calculer ça, là c'est clairment plus lent. 75% plus lent pour 16 points
DrakHors ligneRédacteurPoints: 1923 Défis: 38 Message

Citer : Posté le 01/07/2016 17:26 | #


Est-ce que quelqu'un pourrait m'expliquer le principe de vos "matrices de rotation" ?! J'en entends sans arrêt parler quand je passe dans le coin !
Eon the Dragon : version 1.2
Let's have a look!
Marre de ces RPGs qui t'imposent des classes, des compétences et des sorts ? Crée tes propres capacités sur Eon the Dragon ! Des monstres, des dragons et des combats aussi épiques que difficiles t'attendent !
Un RPG unique et immense t'attend ! Joue dès maintenant à Aventura, le Royaume Poudingue !
Vous aussi, soyez swag et rejoignez Planète Casio !
NinestarsHors ligneMembrePoints: 2247 Défis: 22 Message

Citer : Posté le 01/07/2016 17:27 | #


Bien sûr, Tu as vu les matrices en cours ?
DrakHors ligneRédacteurPoints: 1923 Défis: 38 Message

Citer : Posté le 01/07/2016 17:28 | #


Oui, j'étais en spé maths cette années !
Eon the Dragon : version 1.2
Let's have a look!
Marre de ces RPGs qui t'imposent des classes, des compétences et des sorts ? Crée tes propres capacités sur Eon the Dragon ! Des monstres, des dragons et des combats aussi épiques que difficiles t'attendent !
Un RPG unique et immense t'attend ! Joue dès maintenant à Aventura, le Royaume Poudingue !
Vous aussi, soyez swag et rejoignez Planète Casio !
LephenixnoirEn ligneAdministrateurPoints: 15513 Défis: 136 Message

Citer : Posté le 01/07/2016 17:31 | #


Ninestars a écrit :
C'est à dire ? Je n'ai j'amais vu l'utilisation des complexes dans ce genre d'application.

Wait, je suis le seul à faire du Super DrawStat en complexes ? --'

Ninestars a écrit :
Enfin il faut être maso pour calculer ça, là c'est clairment plus lent. 75% plus lent pour 16 points

Ben ouais, c'est pour ça que je disais que ce serait « fatalement plus lent ».
NinestarsHors ligneMembrePoints: 2247 Défis: 22 Message

Citer : Posté le 01/07/2016 17:33 | #


Et bien, pour faire simple tu as un point de coordonnées (x,y) On peut créer une matrice 2x1 avec ces coordonnées (verticale donc)
Si on fait le produit de cette matrice par une autre matrice particulière dite "de rotation" alors le résultat (qui est une matrice 2x1 toujours) correspond aux coordonnées de ton point après rotation.
regarde la tête de la matrice sur wiki

Ajouté le 01/07/2016 à 17:35 :
Lephenxnoir a écrit :
Wait, je suis le seul à faire du Super DrawStat en complexes ? --'
Surement, c'est une bonne technique que je n'ai pas mis dans mon tuto
DrakHors ligneRédacteurPoints: 1923 Défis: 38 Message

Citer : Posté le 01/07/2016 17:38 | #


Comment ça se présente ? C'est une matrice 1x2 fois une matrice 1x2 ou un matrice carrée d'ordre 2 fois une matrice 1x2 ?
Eon the Dragon : version 1.2
Let's have a look!
Marre de ces RPGs qui t'imposent des classes, des compétences et des sorts ? Crée tes propres capacités sur Eon the Dragon ! Des monstres, des dragons et des combats aussi épiques que difficiles t'attendent !
Un RPG unique et immense t'attend ! Joue dès maintenant à Aventura, le Royaume Poudingue !
Vous aussi, soyez swag et rejoignez Planète Casio !
NinestarsHors ligneMembrePoints: 2247 Défis: 22 Message

Citer : Posté le 01/07/2016 17:41 | #


Comme ça lien
Avec x et y les coordonnées de ton point et x' et y' après la rotation. Refait le calcul matrciel à la main, il te donne deux équations (x' = cos(t) x - sin(t) y et y' = sin(t) x + cos(t) y)
Dark stormEn ligneMembre d'honneurPoints: 10824 Défis: 176 Message

Citer : Posté le 01/07/2016 17:41 | #


En gros t'as ça :

Y = MX


Avec Y la matrices des nouvelles coordonnées (2×1 si en 2D, 3×1 si 3D)
M la matrice de rotation (2×2 ou 3×3)
X la matrice des anciennes coordonnées (2×1 ou 3×1)
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Páranÿe quetë Quendya
Pages : 1, 2Suivante

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2019 | Il y a 76 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd