convertir des coordonnées

(Cliquez-ici pour accéder à la version originale de cette discussion avec couleurs et images)







Posted by: coucfr

bonjour
suite à la découverte du programme de johnny chung lee pour transformer une wiimote en tableau numérique, (avec ces qualités, et ces défauts) j'essaye de ré-écrire le programme à l'aide d'un scripte glovepie (plus facile à maitriser que le visual c# express 2005). Malheureusement, je bute sur la conversion des coordonnées transmise par la wiimote pour guider le pointeur de la souris.
je cherche donc la formule mathématique qui permet de convertir des coordonnées x;y à l'intérieur d'un quadrilatère quelconque (rectangle vue par la caméra infrarouge de la wiimote) en coordonnées dans un rectangle (écran de l'ordinateur).
pour mieux comprendre, voici un schéma du tableau vue par la wiimote :
http://faure.landes.free.fr/fichier/tbi.JPG
je connais les points de x1;y1 à x4;y4 (étape de la calibration du tableau) le point x5;y5 (position du pointeur infrarouge vue par la wiimote), et je voudrais calculer le point x6;y6 qui correspond à la position du curseur de ma souris.

pour les personnes qui veulent en savoir plus sur ce tableau numérique, voir : http://www.cs.cmu.edu/~johnny/projects/wii/
les défauts que je cherche à corriger :
- fonction mouvement de la souris, clic gauche, clic droit (actuellement seul le clic gauche est géré)
- défaut sous powerpoint la fonction surligneur et stylos fonctionne mal (voir video : http://fr.youtube.com/watch?v=F9IYX1M7gJY )

D'avance merci aux courageux et fort en math



Posted by: coucfr

ce que j'ai essayer:
- calculer la position de X en fonction de delta X et de l'écart entre X0 et la droite x1;y1 - x3;y3 . Le problème est que delta X et de l'écart entre X0 et la droite x1;y1 - x3;y3 varient en fonction de Y (et je ne trouve pas la formule)

- calculer la même chose pour Y



Posted by: Patastronch

pour ma part voila comment je ferais :

Imagine le point A se situant quelque part sur la droite ((x1,y1)(x3,y3)).
Imagine le point B se situant sur le coté oposé à la meme proportion de distance entre les 2 extrémités. La droite formées par AB correspond a la ligne horizontale dans ton nouveau repere se situant a la meme proportion de distance des 2 horizontales extremes de ton rectangles.
Pareil pour les verticales (avec un point C et D). De cette maniere tous points dans ton quadrilatere possede une coordonnée unique dans le second repere.

Ainsi pour un point (x5,y5) donné voila comment je calculerai sa position dans le second repère :

Pour tout point A je regarde si (AB) passe par (x5,y5).
Pour tout point C je regarde si (CD) passe par (x5,y5).
Dans la théorie on est dans le continu donc ces points existent, dans l apratique tu es dans un repere discret, donc il se peut qu'aucune droite ne passe par (x5,y5). Mais il te suffit alors d'encadrer le point par 2 droite (AB) successives et de renvoyer le point approximatif qui se trouve au milieu des 2 points A trouvés.

Une fois A=(Xa,Ya) et C=(Xc,Yc) déterminés les coordonnées de (x5,y5) dans le nouveau repère sont : (L*Xc/(x2-x1),H*Ya/(Y1-Y3)) avec L (resp. H) la largeur (resp. la hauteur) de ton second repère.

Je sais pas si j'ai été clair. Le plus difficile à programmer (et a optimiser) est de déterminer le point A et C.



Posted by: coucfr

je crois que la méthode est bonne, mais je ne sais pas comment la mettre en application.
concrètement, quelle formule dois-je utiliser pour trouver les coordonnées x6;y6

il me faudrais une formule du genre:
x6 = quelque chose * x5 + autre chose / etc (fonction de x1 à x5 et y1 à y5)
y6 = quelque chose * y5 + autre chose / etc (fonction de y1 à y5 et x1 à x5)

j'étudie ta piste quand même (mais compétence en math sont limité alors je n'est pas beaucoup de chance d'y arriver)
merci



Posted by: Patastronch

Citation:
Posté par coucfr
je crois que la méthode est bonne, mais je ne sais pas comment la mettre en application.
concrètement, quelle formule dois-je utiliser pour trouver les coordonnées x6;y6

il me faudrais une formule du genre:
x6 = quelque chose * x5 + autre chose / etc (fonction de x1 à x5 et y1 à y5)
y6 = quelque chose * y5 + autre chose / etc (fonction de y1 à y5 et x1 à x5)

j'étudie ta piste quand même (mais compétence en math sont limité alors je n'est pas beaucoup de chance d'y arriver)
merci


A mon avis il ya pas de formule miracles comme t'aimerais, ou alors je vois pas.

Comment je le programmerais naivement :

Je défini un pas de P.
Pour chaque A allant de (x3,y3) à (x1,y1) avec un pas =P faire
Calculer la position B correspondant au point A.
Si (AB) passe strictement en dessous de (x5,y5) alors ne rien faire.
Sinon retenir A et sortir de la boucle.
Fin pour

Pour chaque C allant de (x1,y1) à (x2,y2) avec un pas =P faire
Calculer la position D correspondant au point C.
Si (CD) passe strictement à gauche de (x5,y5) alors ne rien faire.
Sinon retenir C et sortir de la boucle.
Fin pour

x6=L*Xc/(x2-x1)
y6=H*Ya/(y1-y3))


Plus ton pas P sera petit, plus l'algorithme sera lent (mais ca reste relatif, on est en O(max(H/P,L/P)) pour calculer les coordonnée d'un point, c'est polynomal donc viable) mais plus le calcul de x6,y6 sera précis.



Posted by: coucfr

j'avais bien penser à cette méthode, mais elle reste compliquer à mettre en œuvre, (notamment dans le cas ou le point réelle est entre deux droites calculer), la programmation n'étant ni très esthétique, ni très précise (fonction du pas P), j'aurais préférais utiliser une vrais formules mathématique (pas trop magiques de préférence )
merci pour tes suggestion



Posted by: Patastronch

Pour le pas P il suffit de prendre la precision de ton repere d'arrivée. Prendre plus precis ne servira a rien, et l'approximation deviendra juste par la force des choses.

Par exemple si ton second repere est sur 500x300 pixels, alors tu prend comme pas P :1/300 pour la hauteur et 1/500 pour la largeur.

Ensuite niveau programmation c est pas compliqué en réalité. Par contre c'est moins beau qu'une belle fonction analytique de transformation des coordonnées je te l'accorde.



Posted by: coucfr

merci pour cette piste , je teste
Ca risque quand même de me poser problème car mes compétence de programmeur ne sont pas ultra développé notamment pour la boucle :
Citation:
Pour chaque A allant de (x3,y3) à (x1,y1) avec un pas =P faire
Calculer la position B correspondant au point A.
Si (AB) passe strictement en dessous de (x5,y5) alors ne rien faire.

que je ne sais pas calculer

autrement si quelqu'un voit comment réaliser cette conversion de coordonnées avec une belle formule (ou plusieurs), je suis quand même preneur



Posted by: Patastronch

Ok :
D'abord tu calcul l'equation Y(X) de ta droite ((x1,y1)(x3,y3))
De meme, tu calcul l'equation Z(X) de ta droite ((x2,y3)(x4,y4))

Y et Z sont de la forme aX+b. Si tu pars de (x1,y1) comme premier point pour A(donc en Y(x1), le point A suivant a parcourir sera Y(x1+cos(atan(a))*P) (à vérifier que ca correspond bien a un deplacement de longueur P sur la droite).

Pour calculer le point B en fonction du point A il faut :
Calculer la distance D1 entre (x1,y1) et (x3,y3) (facile a faire je te laisse les calculs).
Calculer la distance D2 entre (x2,y2) et (x4,y4) (facile a faire je te laisse les calculs).
Calculer la distance Da entre A et (x1,y1)
Calculer le rapport R=Da/D1
En déduire la distance Db entre B et (x2,y2). Db=Da*D2/D1
En deduire les coordonnées de B = (x2+cos(atan(a))*Da*D2/D1, Z(x2+cos(atan(a))*Da*D2/D1)) (pareil faut vérifier que j'ai pas fait d'erreur , je fais les calculs a la va vite de tete la).

Maintenant qu'on a les coordonnées de A et de B, tu calcul l'equation E de sa droite. Et enfin tu regarde ou se trouve le point (x5,y5) par rapport a E.

Pour la boucle de C et D c'est quasiment la meme chose.



Posted by: coucfr

encore merci pour ton aide.
je vais essayer de faire ça



Posted by: coucfr

En attendant de mettre en place ta solution, voici la méthode que j'utilise actuellement :

la position de la souris sur x est donnée par un chiffre entre 0 et 1 (idem pour y)

ma méthode actuelle consiste donc à faire le calcul suivant:
x6 = (x5 - x1 - ((x3-x1)*y6)) / { x4 - x3 - [((x4 - x3) - (x2 - x1)) * y6] }

y6 = (y6" - 1) * -1
ce calcul et là pour inverser l'axe des y car les coordonnées de la souris commence dans le coin haut gauche et non pas par le coin bas gauche


y6" = (y5 - y3 - ((y4-y3)*x6)) / { (y1 - y3 - [((y1 - y3) - (y2 - y4)) * x6] }

résultat :
- sur les côtés gauche et droite, la position semble correcte sur les axes X et Y.
- au centre de l'écran, la position semble correcte uniquement sur l'axe Y. il y à un gros décalage sur l'axe X (le curseur est à droite de la position demandée)

je présume que :
- mes formules sont incomplètes.
- sur l'axe Y, au centre de l'écran il doit aussi y avoir un décalage, (moins prononcer car la distorsion sur l'axe y est faible)
- cette distorsion est due à l'inclinaison des côtés de mon quadrilatère
- cette distorsion dépend de cet angle d'inclinaison

question :
- mes équations sont-elle sur la bonne piste ??
- comment corriger cette distorsion ??











-