Trygonononono ... probleme elements qui suis la souris... [Résolu]

f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 31 juil. 2006 à 14:16 - Dernière réponse : DeltaFX 459 Messages postés lundi 19 avril 2004Date d'inscription 8 avril 2009 Dernière intervention
- 1 août 2006 à 15:10
Salut a tous,

voila le probleme, j'essaye de resoudre depuis ce matin un petit truc mais non sans peine.

Le resultat theorique :
Deplacer le curseur au dessus d'une paintpox et un elements graphique (image par exemple) essaye de rattraper le curseur de la souris.

Le resultat pratique :
une catastrophe. ça fait n'importe quoi, quand je n'ai pas l'erreur de calcul en virgule flottante.

en gros ce que je fait :

calcul de la distance entre position de l'element et le curseur de souris ... (trygonometrie)
grace a la formule AC² = AB² + BC²
d'ou le code :
AC := sqrt( sqr(AB) + sqr(BC) );

ça c'est parfait ça fonctionne.

ensuite, pour connaitre la direction je recupere l'angle de cette trajectoire avec la formule :
cos(Â) = AB/AC
d'ou le code :
A := ArcCos( AB/AC );

ici ... ça marche mais parfois j'ai le probleme de calcul en virgule flottante ... mmm ... surtout quand j'ai une erreur dans les formule que j'applique ensuite.

Quand je bouge la souris, je recupere deja les coordonnées du curseur, je travail sur une paintbox qui prend toute la zone de fiche donc X ou Y ou ça c'est pareil (au depart c'etait dans un timer d'ou le code)  :

MPX := Mouse.CursorPos.X - ClientOrigin.X;
MPY := Mouse.CursorPos.Y - ClientOrigin.Y;

ensuite je calcul la distance entre ces coordonées et celle du centre de mon elements a faire bouger :

WHYP := sqrt( sqr( MPX - ELM.X ) + sqr( MPY - ELM.Y ) );

ça c'est nickel, j'ai toujours la bonne taille ... (hummm)
puis l'angle de trajectoire MP > ELM et recherche le signe (+ ou -) grace a une petite fonction que j'ai fait qui renvois +1 si c'est positif, 0 si zero et -1 si negatif (GetSign), pour corriger la position avec l'inversion de l'axe des Y, si l'origine de l'ecran etait en bas a gauche ça me faciliterais la tache ^^ :

ATJ := ArcCos( (MPX-ELM.X) / WHYP ) * (GetSign( MPY-ELM.Y ));

tout cela fonctionne a peu prés bien ... en theorie la formule et bonne.
mais viennent les problemes a partir d'ici...

ATJ passe a 180° quand il vas 359.9 a 0.0, en gros ma formule renvois 360° = 180°
et donc ... mon point se retrouve a l'opposé de sa position quand il passe a 360° ...
le probleme est que je ne reussis pas a trouver d'ou viens ce probleme ...
j'ai essayer quelque bricolage mais rien ne vas ... ma seule solution serait d'utiliser un tableau de valeurs et de corriger la 360eme.
mais cette solutions me semble bricolo bricolo. surtout que j'aurais 2 entrée a zero ... a moins de jouer avec l'interval tableau mais la encore ... ç'est pas le mieux.

ensuite viens le probleme d'application du mouvement pour que l'element graphique rattrape le curseur.
mais la encore, probleme, il fait n'importe quoi.
En gros ce que je fait c'est :

Diminuer la valeur de WHYP et calculer la nouvelle position de ELM grace a cela :

WHYP := WHYP - 0.1;
ELM.X := round( MPX + (WHYP * Cos( DegToRad( ATJ )) ));
ELM.Y := round( MPY + (WHYP * Sin(DegToRad( ATJ)) ));

( on ne feras pas attention a l'optimisation, le but etant que ça marche meme si ça rame )

et donc la encore, le probleme est que le deplacement fait n'importe quoi, soit il suis correctement mais dés que je bouge la souris WHYP augmente d'un coups et donc l'elements se retouve a des millions de pixels plus loins ... meme avec des controls pour eviter les calculs inutiles ... mais en gros WHYP devrais toujours etre decrementer pour rattraper la position du curseur.
snif ouin.

je pense avoir oublier quelque chose ou alors, je n'utilise pas la bonne methode.
bref, si quelqu'un peu m'aider a trouver la solutions ... franchement je rame.

je ne comprend pas pourquoi alors que je decremente le rayon (WHYP) il me fait n'imp dés que je bouge la souris (quand il ne fait pas n'imp dés le depart)
bref ... si quelqu'un a une piste ou meme un tuto ou autre je suis preneur ... car je rentre relativement bredouille de wikipedia.
et n'ai rien trouver de similaire sur le site... j'ai eplucher plusieurs site sur la geometrie, calcul des angles, des distances mais nada...

merci d'avance, si vous avez du temps a consacrer a ce probleme, qui est plus un probleme de methode et formules qu'un probleme réel de code.
Meme si vous mettez en grand ligne les principes a suivre (algorythmie) j'arriverais a adapter...
Le pire est que j'ai deja vus dans flash un exemple similaire avec une coccinnelle, pas moyen de le retrouver, surrement dispo que dans Flash 6 ou 5 ... si quelqu'un a le FLA ça m'interresse aussi (pas le SWF hein! le FLA! sinon ça sert a rien ^^).

bonne journée a tous.

<hr size="2" width="100%" />Croc (click me)
Afficher la suite 

15 réponses

Répondre au sujet
Caribensila 2671 Messages postés jeudi 15 janvier 2004Date d'inscription 18 janvier 2018 Dernière intervention - 31 juil. 2006 à 18:11
+3
Utile
Salut,
Tu pourrais peut-être t'inspirer de ça:

http://www.zoneflash.net/tutoriaux/t029.php
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Caribensila
Utilisateur anonyme - 1 août 2006 à 02:52
+3
Utile
Salut foxi malgré mon absence (réparation d'un PC) j'ai réfléchis à ton probleme.

Si j'ai bien tout compris tu as 3 points et tu veux dessiner la sinusoîde qui passe par ces 3 points.

Il ya une chose qui me gene dans ton approche :
Les 3 points peuvent tres bien appartenir à un cercle (par exemple le triangle fait par le diametre d'un cercle avec un point de ce dernier est un triangle rectangle). Je n'ai pas poussé le raisonnement plus loin, mais le flaire me fait penser qu'il faut mieux utiliser la technique ci-dessous.

Pour déterminer la fonction sinusoide passant par tes 3 points il faut écrire
y=a*sin (b*x)+c. Comme tu as 3 points M1(x1,y1) M2(x2,y2) M3(x3,y3) ca te fait un systeme à 3 inconnues

Tu obtiens donc

y1=a*sin(b*x1)+c
y2=a*sin(b*x2)+c
y3=a*sin(b*x3)+c

A partir de la deux approches sont possibles :

*Résoudre ce systeme d'équation (si j'ai un peu de temps je m'y pencherai).
*Utiliser un procédure d'itération : ce qui est interresant du point de vue coding.

Une fois que tu as résolu ca tu auras les valeurs de a b et c. Et donc tu auras l'équation de ta sinusoide et tu pourras la tracer.

Le nombre c te permet de connaiter le décalage vertical de ta fonction. Enfin pour un angle de 0° tu as sin0°=0. Hors rien ne prouve que ta courbe passe par le point (0,0).

Le nombre a te permer de jouer sur l'amplitude : en effet un sinus est égal au maximum à 1 et au minimum à -1. Hors tes points ne sont pas tous sur un pixel (...,1).

Le nombre b te permet de jouer sur la périodicité de ta courbe. Ca te permet donc de savoir si tes 3 points seront sur une meme période ou étalé sur 3 par exemple.

N'oublie pas une chose : en math l'axe oy va vers le haut. Donc l'origine (0,0) est le coté en haut à gauche de ton écran. Donc d'un point de vue mathématique tout tes pixels sont négatifs par exemple le pixel (200,400) est en réalité (-200,-400). Il faut donc que tu n'oublies de jouer sur le signe. Ce qui expliquerait peut etre que 360° se transforme en 160°.

Tu peux aussi modéliser ta coube par un cosinus si tu préféres.

J'y réfléchis demain et te poste une formule si je peux

Bon coding

@++
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Utilisateur anonyme
Utilisateur anonyme - 1 août 2006 à 03:49
+3
Utile
Je te propose une autre technique (désolé pour les non matheux mais j'y vais doucement) dans le cas ou ton objet se déplace à la meme vitesse que ton curseur.
Avantage l'orientation des x et des y n'intervient pas.

Ton objet se trouve à un instant donné au point A(xa,ya) et ton curseur se trouve au point C(xc,yc).

La droite qui passe par les points A et C admet une équation du type y=Mx+N.
M=(yc-ya)/(xc-xa)
N=yc-xc*M

Si ton curseur se déplace et se trouve maintenant au point L(xL,yL). L'écart selon l'axe x est xL-xc. Bien ton objet il va se déplacer du meme écart c'est à dire qu'il va etre en un point K(xK,yK). L'écart est xk-xa. Les 2 écarts sont égaux donc xk-xa=xL-xc soit xk=xL-xc+xa (premiere formule à utiliser).

Maintenant que tu as xk et il te faut yk. Evidemment l'objet se trouve sur la droite AC. donc on a yk=M*xk+N (seconde formule).

Coding : le principe pour ne pas t'enlever le plaisir. Tu utilises un timer.
Tu as la position précédente de ton objet et de ta souris c'est à dire A(xa,ya) et C(xc,yc). Lors de l'appel tu récuperes la position nouvelle de ta souris L(xL,yL). Si identiques le truc habituel : un exit. Si c'est différent

1e etape : tu calculs M et N par M=(yc-ya)/(xc-xa) et N=yc-xc*M.
2e etape tu calculs la nouvelle valeur de x pour l'objet par la relation
xk=xL-xc+xa .
3 étape : tu calculs la nouvelel valeur de y pour l'objet par la relation yk=M*xk+N.

Tu dois utiliser un interval rikiki ( tu devras faire des tests) afin que l'écart de position de la souris soit tres faible sinon le rendu va pas etre terrible.

L'avantage de cette technique est que tu n'utilises pas de cosinus donc pas de 360 qui devient 180. Ensuite pour les calculs intermédiaires arrondis les par défaut ca ira tres bien.

Bon coding ;)

@+
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Utilisateur anonyme
DeltaFX 459 Messages postés lundi 19 avril 2004Date d'inscription 8 avril 2009 Dernière intervention - 1 août 2006 à 10:18
+3
Utile
N'utilise pas arccos mais Arccos2. Arccos c'est la version du pôvre qui renvoie un résultat entre 0 et 180° (Pi). Arccos2 est complet.
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de DeltaFX
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 1 août 2006 à 13:29
+3
Utile
Voila! c'est posté ICI!

<hr size="2" width="100%" />Croc (click me)
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de f0xi
DeltaFX 459 Messages postés lundi 19 avril 2004Date d'inscription 8 avril 2009 Dernière intervention - 1 août 2006 à 15:10
+3
Utile
Arccos2 je l'ai trouvé là : http://www.efg2.com/Lab/Library/Delphi/MathFunctions/General.htm

Il est pas dans D7.

Mais dans ton cas tu peux tres bien utiliser arctan2 pour récuperer ton angle.
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de DeltaFX
jlen100 1651 Messages postés samedi 10 juillet 2004Date d'inscription 25 juillet 2014 Dernière intervention - 31 juil. 2006 à 15:19
0
Utile
salut foxi,

je ne sais pas si j'ai tout compris (j'avoue avoir lu ton post un peu
en travers : un peu long juste après la sieste) mais si c'est pour
faire faire suivre un objet à la souris vas voir dans U_ChoiseVideo de vidoesurveillance 
ou je déplace l'image des caméras pour les placer sur l'ecran choisi
avec ancrage sur l'écran ou ....dansla poubelle . ici je ne me suis pas
trop embêter avec la position de la souris par rapport à l'élément
puisque elle est toujours en haut et au centre mais ça pourrait
s'améliorer.


@+

jlen
Commenter la réponse de jlen100
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 31 juil. 2006 à 17:47
0
Utile
merci jlen mais c'est pas ça du tout...
il ne s'agit pas de juste deplacer un elements au meme niveau que le curseur mais de faire en sorte qu'un elements cherche a toujours rattraper le curseur de la souris ...

cad on n'est jamais a la position du curseur ... on essaye juste de le rattraper...

<hr size="2" width="100%" />Croc (click me)
Commenter la réponse de f0xi
jlen100 1651 Messages postés samedi 10 juillet 2004Date d'inscription 25 juillet 2014 Dernière intervention - 31 juil. 2006 à 17:52
0
Utile
il me semblait bien que je n'avais pas tout compris!!
Commenter la réponse de jlen100
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 31 juil. 2006 à 21:42
0
Utile
Han si simple!

merci Cari! c'est tout a fait ce que je cherchais, reste maintenant a convertir l'AS en Delphi ...

merci mille fois.

<hr size="2" width="100%" />Croc (click me)
Commenter la réponse de f0xi
Utilisateur anonyme - 1 août 2006 à 03:08
0
Utile
Bien en fait non j'ai rien compris : lol. Désolé
Commenter la réponse de Utilisateur anonyme
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 1 août 2006 à 08:32
0
Utile
Merci a toi francky ^^

en effet, c'est un peu complexe d'essayer de resoudre ce genre de probleme avec de la pure trygo ...
mais y'a des astuces plus simple que la triangulation de position et les vitesse angulaire ... :)

la je regarde pour la soluce en flash, c'est vraiment bien foutus...
avantage je connais bien l'AS et flash et donc je vais pas avoir de probleme pour le faire.
vus que flash lit toujours en continus ça reviens a utiliser un timer regler dans un interval 45 - 80 pour etre entre 12 ... 22 FPS
reste a utiliser l'evenement OnTimer comme si il s'agissait de l'evenement onEnterFrame.

je posterais le code dans les sources pour ceux que ça interresse.

<hr size="2" width="100%" />Croc (click me)
Commenter la réponse de f0xi
Caribensila 2671 Messages postés jeudi 15 janvier 2004Date d'inscription 18 janvier 2018 Dernière intervention - 1 août 2006 à 10:09
0
Utile
Moi, ça m'intéresse! 
Voilà quelques temps que je gardais ce tuto en flash sous le coude pour le traduire, et ça va se faire tout seul... 

Elle est pas belle, la vie? 
Commenter la réponse de Caribensila
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 1 août 2006 à 10:47
0
Utile
YOUPI!

ça marche du feu de dieu! je m'eclate comme un dingue ... faut vraiment pas grand chose.

je refact. le code et les commentaires et je le poste dans les sources.
ça vaut vraiment le detour.

de plus c'est le genre d'effet qu'on ne trouve qu'en flash la plupart du temps.
ce serat donc original et vraiment interressant pour tout le monde.

<hr size="2" width="100%" />Croc (click me)
Commenter la réponse de f0xi
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 1 août 2006 à 11:03
0
Utile
@DeltaFX : trés bon conseil qu'est le tiens,
en effet je ne savais meme pas qu'il existait un ArcCos2 (non trouver dans Math sous D7 ?!).
et en effet ArcCos utilise ArcTan2 qui renvois X dans l'interval -PI..PI radians donc X ne peu jamais etre egal a 0

function ArcCos(const X: Extended): Extended;
begin
  Result := ArcTan2(Sqrt(1 - X * X), X);
end;

ou est-ce que tu as cette fonction dans une unité speciale math ? car d'origine dans D7 elle n'y est pas ...
peut etre est elle implementée dans delphi 2005 ?
si c'est le cas pourrait copier coller son code ici ?

<hr size="2" width="100%" />Croc (click me)
Commenter la réponse de f0xi

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.