Calcul de point après rotation

Discutez d'informatique ici !
Fletcher Pink
Messages: 5
Enregistré le: 07 Oct 2014, 19:41

Calcul de point après rotation

par Fletcher Pink » 07 Oct 2014, 20:04

Bonjour,
Je me passionne depuis quelques années pour la programmation PHP et je suis coincé depuis quelques jours sur un problème… de math !
Petit, ma prof de math désespérait de mon hermétisme à cette matière.

Alors voilà mon problème :
Je souhaite recadrer une image et surtout pouvoir la redresser. Mais comment obtenir les coordonnées x-y du coin supérieur gauche lorsque l'axe de rotation est, lui, au centre de ce même rectangle ?

Je nage… Ou plutôt, je me noie !

Alors si une bonne âme pouvait me guider en prenant en compte que mon niveau de math doit être approximativement 5ème… (j'ai 39 ans !!!)

Un exemple valant mieux qu'un long discours : voici un modèle assez explicite (cliquez sur les valeurs de changement d'axe en bas)

Le but étant que les sélections bleu et rouge recadrent la même chose.

En haut de page, un tableau récapitule l'ensemble des données que je connais. En bleu, celles se rapportant au cadre bleu et en rouge, celles qui se rapportent au cadre rouge.
;-)

Les deux dernières lignes du tableau affichent les formules mathématiques que j'applique pour obtenir le résultat.

Voilà, je reste à votre disposition.

Bien cordialement,



Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6478
Enregistré le: 22 Nov 2007, 14:00

par fatal_error » 07 Oct 2014, 20:48

salut,

je comprends rien de ce que t'attends.
A gauche, c'est l'image de référence, c'est bête mais faut le préciser :hum:
A droite, je sais même pas ce que t'essaies de faire.
D'ou sort ton rectangle rouge, connais-tu ses coordonnées, ou tu cherches à les trouver?
pourquoi ton image est-elle tournée, tu cherches un angle ou c'est imposé?

Tu dis que tu connais les données en rouge, sauf que... ya toutes les données fixées du coup...

ps: mieux vaut un exemple qui marche même si c'est fait à la main plutot que des exemples qui marchent pas :D

ps: tu peux également préciser à quoi ressemble ton repère...s'agit-il de
Code: Tout sélectionner
--->y
|
|
v x

ou bien
Code: Tout sélectionner
------>x
|
|
v y
la vie est une fête :)

Ingrid55
Membre Relatif
Messages: 162
Enregistré le: 06 Juil 2014, 23:51

par Ingrid55 » 07 Oct 2014, 21:51

Est-ce qu'il essaie de savoir de faire coïncider le centre du rectangle en fonction de l'inclinaison (enfin rotation) avec l'image de réference (image gauche) ?
Lorsque tu parles de recadrage , ceci implique que l'inclinaison change mais c'est comme si le repère (change d'axe) de l'image de droite change même si à l'origine c l'image de référence ...
Ou bien ta formule fausse un peu les résultats , en voyant l'image pour une rotation de 10° , il y'a une erreur de 20° à peu prés .
Aussi, dans ton image de référence , le centre du rectangle ne bouge pas (mais le cadrage du rectangle si) .
Mais connais-tu les coordonnées du rectangle rouge (dans son repère ) ?

PS : Globalement , tu dois t'inspirer d'un cercle trigonométrique ...
Est-ce que tu recadre ton rectangle en fonction d'un déplacement de x ou bien de y ?
Aussi , à ne pas confondre recadrage et redressement de l'image avec celui du rectangle (qui bouge ) ...

Sur quelles bases as-tu crée ses formules ?

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6478
Enregistré le: 22 Nov 2007, 14:00

par fatal_error » 07 Oct 2014, 23:31

juste pour info, je sais pas si c'est ca, je pense pas parce que c'est quand même super balourd,
http://jsfiddle.net/2cm5qdph/

tu n'as qu'à tourner la photo de -l'angle que tu as tourné le rectangle...
après si c'est juste un problème de redimensionnement de l'image (parce que il faut agrandir les bords parce que la photo a tourné), c'est juste un vulgaire problème de translation...
la vie est une fête :)

Fletcher Pink
Messages: 5
Enregistré le: 07 Oct 2014, 19:41

par Fletcher Pink » 08 Oct 2014, 11:07

Merci de votre implication !

Méa culpa, je reconnais que mes explications manquent de clarté. Quand on a la tête dans le guidon, on pense à tort que tout le monde à le même point de vue.

Voici donc les précisions et autres explications :
COORDONNÉES
x = axe horizontal
y = axe vertical

IMAGES
Image de gauche = image de référence
Image de droite = résultat

APPLICATION
J'ai développé un petit script (javascript puis PHP) qui me permet de recadrer et redimensionner une image selon une sélection définie (cadre bleu). La sélection bleue peut être déplacée.

ROTATION
Je souhaite ajouter une fonction me permettant de redresser une image en même temps qu'elle sera recadrée. Pour cela :
• j'incline ma sélection bleue de x° (angle de rotation variable, axe de rotation au centre de ma sélection)
• j'envoie au serveur PHP :
[INDENT]- la position x et y de ma sélection bleue hors rotation (la rotation affichée n'est qu'un leurre CSS)[/INDENT]
[INDENT]- l'angle de rotation[/INDENT]
[INDENT]- les largeur et hauteur de ma sélection bleue[/INDENT]
[INDENT]- les largeur et hauteur de l'image originale[/INDENT]
• l'image est inclinée par PHP et s'en retrouve agrandie. Je récupère :
[INDENT]- les largeur et hauteur de la nouvelle image[/INDENT]

RECADRAGE
Le recadrage par PHP implique que la zone sélectionnée soit un rectangle posé "à plat" sur l'axe x. Ce qui explique que mon image de droite soit inclinée.

MON PROBLÈME
Je dois faire coïncider les sélection bleue et rouge de manière à recadrer exactement les mêmes partie de l'image. Or :
• les coordonnées x et y de la sélection bleue sont faussées car la sélection bleue a subi une rotation par son centre.
• le positionnement de la sélection rouge doit prendre en compte l'agrandissement de l'image

MON ATTENTE
Je cherche une formule mathématique qui me permettrait de :
• trouver les nouvelles coordonnées x et y de la sélection rouge après une rotation horaire et antihoraire de la sélection bleue.

LES RÉSULTATS DU TABLEAU
Les résultats de position en rouges sont le résultats de calcul des formules en bas du tableau et sont bien évidemment faussés car mes calculs sont erronés. Ils me permettent de tenter de comprendre. (sans succès, je vous l'accorde).
Quant aux formules, comme je le précisais, je suis vraiment à plaindre pour ce qui est des mathématiques. Je les ai trouvé sur internet au gré de recherches et les ai "tordu" dans l'espoir que le hasard fasse bien les choses. Elles sont ce qui se rapproche le plus de mon souhait (oui, vous pouvez rire…)

Voilà, j'espère avoir été plus clair. Si ce n'est pas le cas, demandez moi.

Encore merci.

Bien cordialement

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6478
Enregistré le: 22 Nov 2007, 14:00

par fatal_error » 08 Oct 2014, 16:54

re,

ben si j'ai bien compris, la position de mon rectangle rouge est correcte.
le problème c'est juste que j'ai une image tronquée.
Si on suppose que je tronque pas l'image, il suffit de translatter le rectangle rouge.

Le seul obstacle c'est donc à partir de l'image
Code: Tout sélectionner
               
A                B   [COLOR=Green]+[/COLOR]   ^
[COLOR=Green]+----------------+[/COLOR]   [COLOR=Green]+[/COLOR]  / \
|                |     /   \
+----------------+     \    \
D                C      \  /
                         \/

de calculer les deux offsets qu'on génère en tournant l'image.
(en vert l'offset par rapport au bord supérieur de la figure de gauche)

Donc tu prends la matrice de rotation M de ton image:
a -b
b a
avec a=cos(-angle) et b=sin(-angle)
Tu calcules les images A,...D
Code: Tout sélectionner
[A',B',C',D'] = [A,B,C,D].forEach Point
 return M*Point
fin

Puis tu récupères le point le plus haut et le plus à gauche
Code: Tout sélectionner
mostLeftPoint = [A',B',C',D'].sort Point1, Point2
 return Point1.x - Point2.x


Tu calcules l'offset généré:
offsetLeft = abs(mostLeftPoint - A.x)

Et du coup tu déplaces ton rectangle rouge... de +offsetLeft
pareil pour les y

A tester cela dit
la vie est une fête :)

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6478
Enregistré le: 22 Nov 2007, 14:00

par fatal_error » 08 Oct 2014, 23:09

voilà qui est donc mieux je pense
http://jsfiddle.net/2cm5qdph/1/

donc grossomodo il faut procéder ainsi:
soit ton image de référence qui represente un rectangle ABCD
soit C le centre du rectangle bleu.

Pour chaque point du rectangle ABCD
A' = M(A-C)+C
finPour
avec A' l'image de A par la rotation de centre C et d'angle celui de la matrice de rotation M

Ensuite tu récupères le point plus à gauche, au dessus, à droite, et en dessous (parmi A'B'C'D')
tu déduis la taille de la nouvelle image:mostRight - mostLeft sur les x, mostBottom - mostTop sur les y
Ca veut dire que le point le plus à gauche (par exemple mettons c'est B', et mettons il vaut x:-10,y:42
il faut lui appliquer une translation de x = +10 pour que dans ta nouvelle image, il soit sur la bordure.

Ta translation à appliquer sur le rectangle rouge est donc:
l'offset du point le plus à gauche sur les x
l'offset du point le plus en haut sur les y
la vie est une fête :)

Ingrid55
Membre Relatif
Messages: 162
Enregistré le: 06 Juil 2014, 23:51

par Ingrid55 » 08 Oct 2014, 23:22

Cool mais là il n'y a plus de rotation par le centre du rectangle .
D'où t'es venu l'idée de penser à une matrice de rotation M ?

Est-ce que tu penses que cet algo pourrait être transcrit avec le langage python ?

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6478
Enregistré le: 22 Nov 2007, 14:00

par fatal_error » 08 Oct 2014, 23:25

Cool mais là il n'y a plus de rotation par le centre du rectangle .


je comprends pas ce que tu veux dire. l'image est rotatée par le centre du rectangle

et oui tu écris le programme en ce que tu veux.
(avec un peu de chance peut etre que Rockleader te le fera en ARM.
:ptdr: )
la vie est une fête :)

Ingrid55
Membre Relatif
Messages: 162
Enregistré le: 06 Juil 2014, 23:51

par Ingrid55 » 08 Oct 2014, 23:31

Mdr :hum: à la base , déjà quels sont coordonnées du repère ?
C'est bien beau de connaitre une fonction qui fait la rotation d'une image , mais c très classique :zen:

L'algo est très complexe à comprendre dans son intégralité , mais entre imaginer et coder : y'a une grosse différence :ruse:

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6478
Enregistré le: 22 Nov 2007, 14:00

par fatal_error » 08 Oct 2014, 23:43

Mdr à la base , déjà quels sont coordonnées du repère ?

je sais pas de quel repère tu parles
C'est bien beau de connaitre une fonction qui fait la rotation d'une image , mais c très classique

ben en fait nan c'est pas trivial de rotater une image. Tout simplement parce qu'un pixel à coordonnées entières peut se retrouver avec des coordonnées flottantes et que si tu le tronques, certains pixels de l'image de destination n'auront pas d'antécédents...
ya des algorithmes certes, mais il faut un peu réfléchir...

L'algo est très complexe à comprendre dans son intégralité , mais entre imaginer et coder : y'a une grosse différence

ya rien de complexe, ni l'algo ni le code (enfin ptet comprendre le mien parce que j'ai fait ca à la onagain, et c'est assez atroce). Le plus dur à comprendre c'est ce qu'attend Fletcher Pink. Depuis qu'il a fait sa jolie et précise description c'est plus clair, mais on est jamais à l'abri d'une error :lol3: .
la vie est une fête :)

Fletcher Pink
Messages: 5
Enregistré le: 07 Oct 2014, 19:41

par Fletcher Pink » 09 Oct 2014, 20:06

Tout d'abord, merci pour tout !

J'ai donc essayé de comprendre les explications et démonstrations de Fatal_error. Malheureusement, comme je le précisais, je suis hermétique aux mathématiques et ce malgré moi, car j'aimerai tant…

L'exemple modifié

Cela dit, je me suis dis que le meilleur moyen de comprendre était de placer des repères (créés dynamiquement).

Parmi les repères créés, le cercle blanc au centre de chaque image sur lequel doit toujours se trouver le point central de chaque sélection (rouge ou bleue).

Et j'ai réussi !

Voici la formule que j'utilise :
[HTML]
x_rouge = largeur_image_inclinee/2 + (distance_entre_centres_blanc_et_rouge * cos(135 + angle_de_rotation)) - largeur_de_la_selection/2;

y_rouge = hauteur_image_inclinee/2 + (distance_entre_centres_blanc_et_rouge * sin(135 + angle_de_rotation)) - largeur_de_la_selection/2;[/HTML]

Mais… Me direz-vous, mais… c'est quoi ce "135" ? La moitié de 270 ? 180 + 90 ?

Et bien je n'en sais rien mais c'est en ajoutant cette valeur que tout colle.

La suite damain ou je vais vérifier avec d'autres formats d'image et angle de rotation.

En attendant, si quelqu'un sait ce que vient faire ce nombre, je prends.

Merci à tous.

Edit :
Je confirme. Le chiffre 135 ne colle plus avec une image plus grande. Donc… J'y replonge… !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6478
Enregistré le: 22 Nov 2007, 14:00

par fatal_error » 09 Oct 2014, 21:56

Image

en noir l'image.
En noir pointillé, la même image
en rouge, la même image, mais avec l'angle de rotation
La largeur de la nouvelle image est donnée par largeur = C'.x - A'.x
l'offsetLeft w est donné par w = A'.x - D.x = A'.x
vu que D.x ==0
on déduit h l'offsetTop de la même manière.

Maintenant Tu prends le point A(0,0) exprimé dans le repère du rectangle noir.
Dans le repère du rectangle vert, A_vert = (0-w, 0-h)
Et pour tout point de ton image, tu appliques cette translation pour l'exprimer dans ton repère associé au rectangle vert.

Si tu comprends pas, il faut dire où, mais dire tu comprends rien ca mène nul part.

edit: un peu de clenaup plus utilisation de l'api.
Toujours plus de steven XD! http://jsfiddle.net/2cm5qdph/3/
la vie est une fête :)

Fletcher Pink
Messages: 5
Enregistré le: 07 Oct 2014, 19:41

par Fletcher Pink » 10 Oct 2014, 17:42

Bonjour,
Je suis désolé de passer pour une bête de foire ignare et décérébrée mais je ne comprends pas un mot de ce que tu tentes de m'expliquer. Ou plutôt, toute tentative de reproduction de ton exemple est totalement infructueuse. Même comprendre ton super code est un enfer. Tu vois le niveau ?

Toutefois, étant légèrement obstiné, j'ai trouvé une solution qui fonctionne :
- je calcule la distance entre le centre de mon image et le centre de ma sélection bleue (hypoténuse)
- je créé un cercle de pixel ayant pour rayon cet hypoténuse et pour centre le milieu de l'image grâce à une boucle for
[HTML]
for($i=0; $i<=360; $i++)
{
$cosinus = cos($angle + $i);
$sinus = sin($angle + $i);
...}
[/HTML]
- lors de la création de ce cercle, je compare chaque point (avec une pertinence -1, 0, +1) avec les coordonnées x et y du centre de ma sélection bleue
- Je connais désormais l'angle de rotation qui me permet d'appliquer simplement ma formule :
[HTML]
x = x_centre_image_inclinee + (rayon_hypothenuse_cercle_de_positionnement * cos(valeur_d_angle + angle)) - largeur_selection_bleue/2;
y = y_centre_image_inclinee + (rayon_hypothenuse_cercle_de_positionnement * sin(valeur_d_angle + angle)) - hauteur_selection_bleue/2;
[/HTML]

Voilà. J'ai bien conscience que c'est une rustine mais je n'ai pas trouvé mieux après avoir travaillé une semaine quasiment 10h par jour. Pas très productif, tout ça…

Merci encore pour cette tentative d'explications.

Bien cordialement

Ingrid55
Membre Relatif
Messages: 162
Enregistré le: 06 Juil 2014, 23:51

par Ingrid55 » 10 Oct 2014, 18:43

Le résultat de ton travail est plutôt bien et plus précis que le premier :we: (même au niveau des pixels) L'avantage du cercle consiste dans le fait qu'on voit clairement les coordonnées projetés des points formant le rectangle .

Tu as surement du créer une fonction pixel , non ?

Quant au chiffre 135 , comment l'as-tu trouvé déjà (genre coefficient ou bien décalage fixe) ? Et est-ce que ton dernier test prend en compte différentes dimensions d'image ?

Sinon , le petit dessin de @fatalerror résume bien le boulot à faire !

Fletcher Pink
Messages: 5
Enregistré le: 07 Oct 2014, 19:41

par Fletcher Pink » 10 Oct 2014, 21:09

Le chiffre 135…

Figure toi que ma formule précédente tournait dans le vide… Ou plutôt j'ajoutais x pour l'ôter ensuite…
La première étape a consister à mettre en exergue les quartier de cercle en affichant leur valeur, pour y voir clair.

J'ai ensuite compris que 0 + 0 = … ?

Certain voit le monde en chiffres, moi, je suis graphiste. J'ai besoin de voir.

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 4 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite