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
Citer : Posté le 01/07/2016 17:41 | #
En gros t'as ça :
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)
Citer : Posté le 01/07/2016 17:43 | #
ow, wonderful. Je n'y aurais sans doute jamais pensé de toute ma maigre existence...
Citer : Posté le 01/07/2016 17:44 | #
Est-ce que quelqu'un pourrait m'expliquer le principe de vos "matrices de rotation" ?!
Je vais donner une explication à part, pour la complétude peut-être.
Considérons un espace muni d'une base : disons le plan et sa base « classique » constituée des vecteurs i = (1, 0) et j = (0, 1). Considérons maintenant une transformation linéaire, c'est-à-dire qui vérifie « f(constante * point) = constante * f(point) ». Le concept peut sembler bizarre mais ça relève de l'étude des espaces vectoriels.
Dans le plan, il y a surtout deux types de transformations linéaires qui nous intéressent : les rotations, et les homothéties. Je pense que les rotations c'est assez intuitif : on va préciser que ce sont les rotations autour de l'origine. Les homothéties dilatent le plan autour du centre : on peut dire qu'elles multiplient le module des nombres complexes sans changer leur argument.
La propriété des transformations linéaires c'est qu'elles peuvent se représenter par des matrices. Pour ça, il suffit de considérer l'image des vecteurs de la base. Lorsqu'on fait une rotation de θ autour du centre O, je te laisse vérifier avec le cercle trigo qu'on a :
r_θ(j) = -sin(θ) * i + cos(θ) * j
On obtient alors la matrice simplement : il suffit de recopier les coefficients qu'on a écrits sans les déplacer :
[ -sin(θ) cos(θ) ]
Ensuite, il faut rappeler que tout point du plan se décompose de manière unique dans la « base » (i, j). (Le concept de « base » est propre à l'étude des espaces vectoriels. En gros, une base est un ensemble de vecteurs sur lesquels tout vecteur de l'espace se décompose de manière unique). Étant donné un point X, on peut donc écrire X = x * i + y * j car x et y existent et sont uniques. On représente généralement un tel point par la matrice [[x][y]] (notation calto).
En fait la magie se trouve dans le fait que appliquer la transformation revient à calculer le produit matriciel. Si l'on fait le produit matriciel R_θ * X, on a en effet :
Tu retrouves donc les formules que Ninestars et moi avons utilisées (en stockant les coordonnées sur i et j dans deux listes, ou dans les parties réelles et imaginaires de complexes).
Ce concept se généralise à l'espace en trois dimensions. On peut aussi représenter des transformations affines (notamment des translations) en trichant un peu.
Citer : Posté le 01/07/2016 17:48 | #
Je pense que je dormirai moins idiot à l'avenir. Les maths, c'est mâââââgique.
Et dire que je n'en ferai plus !