Voir la version complète : [µLibrary][Aide] Angle, trigonométrie
sdevilcry
02/07/2008, 19h11
Salut à tous, c'est encore moi :)
Voila je suis encore face a un autre problème :s, j'aimerai afficher la bonne frame de mon sprite en fonction de l'appuie de mon styler.
Pour cela, le plus simple aurait été de comparer l'angle en fonction de mon personnage et de l'appuie du styler, je calcule les distance adjacent et opposer, et je fait une tanjante -1 pour avoir mon angle en degrer, le bémole c''est que ca fonctionne mal pourtant a 4 dessus le code et a verifier le debug, on se demande si ca vient pas d'ailleur...
illustration :
http://blog-vince.fr/image/shema.jpg
code :
float get_angle(t_quest *var, float nx, float ny)
{
float hyp;
float a;
float angle;
//j'ai fait different test, d'ou des declaration "hyp, a..."
angle = atanf(ny/nx);
return (angle);
}
void check_direction(t_quest *var)
{
float nx;
float ny;
var->player.left = 0;
var->player.up = 0;
if (ul_keys.touch.x < ((var->player.x >> 4) + 8))
{
nx = (((var->player.x >> 4) + 8) - ul_keys.touch.x);
}
else
{
nx = ul_keys.touch.x - (var->player.x >> 4) - 8;
}
if (ul_keys.touch.y < ((var->player.y >> 4) + 8))
{
ny = (((var->player.y >> 4) + 8) - ul_keys.touch.y);
}
else
{
ny = ul_keys.touch.y - (var->player.y >> 4) - 8;
}
var->player.angle = get_angle(var, nx, ny);
J'ai fait des define pour les -8 +8 qui corresponde a la moitier de la largeur ou hauteur de mon sprite (16*16);
Pour en conclure que m'on angle trouver a la fin n'est pas vraiment celui qu'on espèrer...
Si quelqu'un sait comment avoir cette angle en fonction de ces critières ou bien a d'autre solution, je suis prenant :)
merci encore :)
sdevilcry
02/07/2008, 20h13
Bon problème résolue, j'ai utiliser atan2f, il fait meme le cafer :p
il renvoit un radian, juste a convertir, pour ceux que ca interesser de connaitre l'angle en fonction d'un point précis et du styler, voici le code ;)
float get_angle(t_quest *var, float nx, float ny)
{
float angle;
angle = 0;
if (((var->player.x >> 4) + 8) < ul_keys.touch.x && ((var->player.y >> 4) + 8) > (ul_keys.touch.y))
angle = (atan2f(ny, nx) * 180.0) / M_PI;
else if (((var->player.x >> 4) + 9) > ul_keys.touch.x && ((var->player.y >> 4) + 8) > (ul_keys.touch.y))
angle = 180 - ((atan2f(ny, nx) * 180.0) / M_PI);
else if (((var->player.x >> 4)) > ul_keys.touch.x && ((var->player.y >> 4)) < (ul_keys.touch.y))
angle = 180 + ((atan2f(ny, nx) * 180.0) / M_PI);
else if (((var->player.x >> 4)) < ul_keys.touch.x && ((var->player.y >> 4)) < (ul_keys.touch.y))
angle = 360 - ((atan2f(ny, nx) * 180.0) / M_PI);
return (angle);
}
Merci a tous ;)
Pas très bon pour le CPU les float :p
archipel
02/07/2008, 23h14
ouep j'ai entendu dire que ca coulait le CPU
mieux vaut utiliser les double avec quelques divisions ;)
le code de base étant déja très optimisé je me suis permis d'ajouter des optimisations (des divisions, touça...):fleur:...
double get_angle(t_quest *var, double nx, double ny)
{
double angle;
double playerx,playery, touchx,touchy;
angle = 0.0;
playerx = (double)var->player.x ;
playery = (double)var->player.y ;
touchx = (double)ul_keys.touch.x ;
touchy = (double)ul_keys.touch.y ;
if (((playerx/16.0) + 8.0) < touchx && ((playery/16.0) + 8.0) > (touchy))
angle = (atan2f(ny, nx) / (1.0/180.0)) / M_PI;
else if (((playerx/16.0) + 9) > touchx && ((playery/16.0) + 8.0) > (touchy))
angle = 180.0 - ((atan2f(ny, nx) / (1.0/180.0)) / M_PI);
else if (((playerx/16.0)) > touchx && ((playery/16.0)) < (touchy))
angle = 180.0 + ((atan2f(ny, nx) / (1.0/180.0)) / M_PI);
else if (((playerx/16.0)) < touchx && ((playery/16.0)) < (touchy))
angle = 360.0 - ((atan2f(ny, nx) / (1.0/180.0)) / M_PI);
return (angle);
}
Erf nes, je pige pas. Pourquoi des divisions ? Tant qu'à optimiser, le décalage de bit est bien plus rapide non ? :huh:
+1 pour les floats, c'est super gourmand, qui plus est que dans ton cas à moins d'avoir des millions de sprites suivant tes directions calculées super finement...
Au final tu ne dois avoir besoin que de quelques valeurs bien choisies regroupées dans une table de valeurs.
Ou plus vraissemblablement des secteurs d'écrans à délimiter pour savoir dans quelle direction regarde ton personnage.
Libre à toi de choisir la solution qui te semblera la plus facile à mettre en place.
Ce tuto (http://www.playeradvance.org/forum/showthread.php?t=4374) pourra peut-être être utile...
Erf nes, je pige pas. Pourquoi des divisions ? Tant qu'à optimiser, le décalage de bit est bien plus rapide non ? :huh:
c'etait du second degré ^^, j'ai même mis les trois petits points pour être sur que ca ne loupe pas :ange::cry:
sdevilcry
03/07/2008, 00h33
faut savoir ce qui est plus gourmand entre float et double, nos assistant nous ont dit d'utiliser les float, le traitement sur la ds sera plus rapide ... je pige plus rien la ^^
Erf nes, je pige pas. Pourquoi des divisions ? Tant qu'à optimiser, le décalage de bit est bien plus rapide non ? :huh:
Eu ouai vaut mieux faire des decalages de bits, le traitement des divisions est assez lent... ^^
Par contre je vois l'interet de faire une division de "/ (1.0/180.0)" dans le code que tu as refais, les divisions c'est lent :p
Libre à toi de choisir la solution qui te semblera la plus facile à mettre en place.
Hum j'ai besoin d'un groupement de 8 valeurs, le probleme c est que mon personnage bouge et je peux pas hardcoder le business... sinon je ne me serait pas embêter a calculer les angles
merci de vos conseil
nes faisait de l'ironie là.
Des floats sur DS c'est mal, parce que c'est pas géré en hard. Les doubles, c'est pire.
Si tu as beaucoup de calculs de ce genre à faire, il faudra absolument passer aux fixed points. Après, si c'est qu'une ou deux fois par frame par exemple, tu peux sacrifier un peu de rapidité pour la simplicité.
archipel
03/07/2008, 11h05
Il n'y a pas une technique qui consiste à multiplier la valeur trouvée par un grand nombre puis de le troncaturer pour en faire un entier.
Aprés, pour s'en resservir on le divise pas ce grand nombre
Les calculs d'angles (180° pfff nul), les flottants, les divisions... tout ça pour savoir dans laquelle des 8 directions regarde un perso suivant la position du stylet, à mon avis c'est une perte énorme de ressources alors qu'il est très simple de le faire autrement.
je m'explique, tu as 8 positions donc je suppose que c'est gauche, droite, haut, bas, et les 4 diagonales à 45° ce qui fait de même 8 secteurs angulaires pour savoir dans quelle direction regarde le perso soit en angles les espaces [-22.5°, 22.5°], [22.5°, 67.5°], [67.5°, 112.5°]... secteurs que l'on va appeler respectivement A, B, C, D, E, F, G et H
Prenons maintenant tes nx, ny valeurs entières signées qui représentent la position du stylet par rapport au perso on a les relations suivantes
si nx >= 0 on est dans A B C G ou H
si ny >= 0 on est dans A B ou C
si nx >= ny on est dans A ou B
si 24 * ny <= 10 nx (approximation à partir de la droite y=tan(22.5)*x pour être en dessous) alors on est dans A
sinon dans B
sinon
si ...
Bref je vais pas tout détailler, comme tu peux le voir avec 4 tests et un peu de calculs sur les entier tu peux savoir direct quel sprite utiliser.
je sais pas si c'est moins gourmand que des floats et du atan2f suivi d'une conversion, mais à vu de nez je dirais que ça l'est :p
sdevilcry
03/07/2008, 14h04
hum mouai, a 4 if prés, je sais pas si les ressources prenne une claque... si je ferait 50 calculs de float a la suite je comprendrai mais la je le fait une fois^^ et puis je reste assez précis sur la frame a afficher :D
Sinon la j'utilise des float car le prototypage de atan2f prend en argument deux floats et renvoie un float ;).
Aprés tous mes autres calculs que je fais se font en décalage de bits ^^
merci quand même YoBoY pour ton explication, mais je vais garder ma méthode, je vois déjà la pille de if grandir si je le fait avec la tienne :s
Il n'y a pas une technique qui consiste à multiplier la valeur trouvée par un grand nombre puis de le troncaturer pour en faire un entier.
Aprés, pour s'en resservir on le divise pas ce grand nombre
Si, tu lis mon tuto...
archipel
03/07/2008, 21h42
yep je viens de trouver:)
en meme temps, je savais déja faire donc je n'y avait pas prété attention;)
sdevilcry
04/07/2008, 15h20
c'est ce que je fais pour la position de mon joueur, je fait un décalage de << 4, et pour le redessiner a la fin, bah on remet ça valeur toute petite (>> 4) :)
vBulletin® v.3.7.2, Copyright ©2000-2008, Jelsoft Enterprises Ltd. Tous droits réservés - Version française vbulletin-fr.org