Je travaille dans l'informatique, et pour mon travail, je suis confronté à un problème de mathématiques que je n'arrive pas à résoudre.
Pour bien comprendre le problème, voici le contexte : je développe un logiciel qui lit un fichier XML qui définit comment découper et placer des images dans un plan en 2D. Plus concrètement, je possède une image qui est composée de plusieurs éléments. Les nœuds du fichier XML définissent les "morceaux" d'images à découper (en disant par exemple : "je découpe dans mon image un rectangle de dimensions 30 sur 40 pixels à partir de la position (25,40) en pixels sur mon image"), puis d'autres valeurs vont dire quelles transformations géométriques appliquer pour bien placer, orienter et redimensionner mon image sur le plan 2D.
Voici un exemple de nœud :
- Code: Tout sélectionner
<Image srcX="201" srcY="383" dstX="32.150795" dstY="57.19337" width="31" height="24" a="0.248288766" b="-2.31910777" c="1.91672742" d="-0.27060008" />
Les valeurs dstX, dstY, a,b,c et d sont utilisées pour former une matrice de transformation géométrique qui combine translation, rotation, changement d'échelle (scale) et skew (je n'ai pas le mot français mais c'est la transfo qui fait ça : )
skew
srcX et srcY sont les positions x et y du pixel où on commence le découpage, mais on peut ignorer ces valeurs car elles sont indépendantes de mon problème.
width et height sont la largeur et la hauteur (ou plutôt longueur) du rectangle à découper dans l'image, c'est-à-dire les dimensions du morceau d'image que j'ai découpé.
Malheureusement, mes cours de mathématiques remontent à loin et je ne savais pas comment récupérer les valeurs à partir de la matrice de transformation pour appliquer translation, rotation, scale et skew.
J'ai réussi à trouver un algorithme qui fait ça, en cherchant sur internet, en voici la traduction en français (je mets uniquement la partie qui nous intéresse)
- Code: Tout sélectionner
vecteur translation = [dstX, dstY * -1] (je multiplie par -1 à cause d'un changement de repère, le haut et le bas sont inversés)
On part du principe que a est non nul ou b est non nul :
Soit r = RacineCarre(a² + b²)
---------- Si b > 0 : angleRotation = ACos(a / r)
---------- Sinon : angleRotation = -1 * ACos(a / r)
vecteur scale = [ r ; (a * d - b * c) / r ]
vecteur skew = [ ATan( (a * c + b * d) / r², 0 ]
Cet algorithme marche quand la valeur x de mon vecteur skew est nulle. C'est-à-dire que je récupère les bonnes informations de translation, rotation et scale, mon image est correctement positionnée et orientée sur le plan.
Par contre, dés que j'ai un skew non nul, j'ai un problème de translation. La rotation et le scale restent corrects.
Mon problème est donc le suivant : je n'arrive pas à savoir quelle translation appliquer quand la coordonnée x de mon vecteur skew est non nulle.
Reprenons le nœud d'exemple :
- Code: Tout sélectionner
<Image srcX="201" srcY="383" dstX="32.150795" dstY="57.19337" width="31" height="24" a="0.248288766" b="-2.31910777" c="1.91672742" d="-0.27060008" />
Avec ces valeurs, je trouve :
skew =[ -0.2001287 , 0 ]
translation = [ 32.150795 , - 57.19337 ]
rotation = 83.89 degrés
scale = [ 2.332361 , 1.87703 ]
Tout est correct sauf la translation. En cherchant manuellement les bonnes valeurs (en déplaçant l'image jusqu'à ce qu'elle arrive là où elle doit être normalement), j'obtiens les valeurs suivantes environ :
translation correcte = [32.8 , -50,7]
(avec une marge d'erreur de plus ou moins 1 je dirais)
Je sais aussi que dans tous mes cas, skew.y est nul.
Puisque quand skew.x est nul, la position est bonne, cela m'incite à penser que la position est la suivante :
position finale = [dstX, -1 * dstY] + skew.x * [kx, ky]
où kx et ky sont des valeurs qui doivent dépendre du reste des informations et que je dois calculer.
Mon problème est donc le suivant : comment exprimer les valeurs kx et ky en fonction des informations dont je dispose (c'est à dire les éléments de la matrice de transformation a, b, c, d, dstX et dstY, voire peut-être width et height).
J'ai essayé les calculs suivants pour essayer de trouver un lien me permettant de définir kx et ky en fonction des autres valeurs mais je n'ai rien trouvé actuellement :
- Code: Tout sélectionner
translation = skew.x * Vector2(kx,ky) = goodPos - currentPos = (0.649204999999995 ; 6,49337)
kx ; ky = translation / skew.x = -3,24393752620186 ; -32,4459710176501
1/kx ; 1/ky = -0,308267342364895 ; -0,03082046764623
cos(angle) = 0,106437614426884
sin(angle) = 0,994319382409452
tan(angle) = 9,34180447169347
goodPos/currentPos = 1,02019250223828 ; 0,886466385876545
currentPos/goodPos = 0,980207164634146 ; 1,12807435897436
kx / cos(angle) = -30,4773603172987 => proche de - width (-31) et presque proche de dstX (32.150795)
kx / sin(angle) = -3,26247037279018
ky / cos(angle) = -304,835571450527
ky / sin(angle) = -32,6313371655559 => proche de -dstX (32.150795)
cos(angle)/kx = -0,003492350168084
sin(angle)/kx = -0,306516193477265
cos(angle)/ky = -0,003280457051786
sin(angle)/ky = -0,03064538835557
kx/tan(angle) = -0,347249563618174
ky/tan(angle) = -3,4732016834611
tan(angle) / kx = -2,87977323738144
tan(angle)/ky = -0,287918782477234
Si vous avez une piste que je pourrais explorer, je vous en serais très reconnaissant car je sèche un peu.
En vous remerciant d'avance.








