IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SFML Discussion :

avancer en fonction de la rotation


Sujet :

SFML

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    Août 2022
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Août 2022
    Messages : 5
    Par défaut avancer en fonction de la rotation
    Bonjour, je cherche à faire avancer en continue un sprite en fonction de sa rotation. Je tiens à préciser que sa rotation change tout le temps et que la fonction s'occupant de ça marche trés bien.

    Voici la ligne que j'ai essayé (qui est dans la boucle d'sfml)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    move(cos(this->getRotation()), sin(this->getRotation()));
    la plupart du temps le sprite avance bien mais dés que sa rotation est environ égal à 0 (donc le sprite est orienté vers le haut de l'écran), il s'arrête d'avancer et se met à reculer. j'ajoute aussi que quand le sprite avance en meme temps qu'il tourne, il se met à trembler (je pense que c'est parce qu'il recule et avance en meme temps)

    merci de vos réponses et de votre aide ^^

  2. #2
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 532
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 532
    Par défaut
    peut-être qu'il suffit de tester l'angle ==0.
    Si c'est le cas alors angle=360

  3. #3
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2018
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juillet 2018
    Messages : 104
    Par défaut
    Il se trouve que le getRotation de SFML retourne des degrés alors que les cos/sin classique prennent des radians. Il te faut donc le facteur PI/180 entre les deux.
    Je ne pense pas que ça explique tous tes "symptômes", mais tu peux déjà voir ce que ça arrange. S'il y a d'autres problèmes, il faudra peut-être chercher sur d'autres lignes.

  4. #4
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 633
    Par défaut Plus long & plus court
    Bonjour,

    J'éviterais de faire deux appels pour calculer le cos et le sin car l'angle peut avoir changé entre temps.

    Avec des variables intermédiaires, on peut éviter nombre de recalculs.

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    double RotNew = 0.017453292*getRotation(); // en radians
    if(RotNew != RotLast) { // ou mettre un seuil abs(RotNew -RotLast) > 0.01 par exemple 
       CosLast = cos(Rot);
       SinLast = sin(Rot);
       RotLast = RotNew;
       }
    move(CosLast, SinLast);
    Je présume que ce move accepte des flottants et gère les partie fractionnaires résiduelles ?

    Salutations

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 151
    Billets dans le blog
    4
    Par défaut
    Il recule ? Donc cos retourne < 0 ? Alors que tu vas vers le haut ?
    Est-ce que en haut a une rotation de 90 ou de 0 et tu oublies d'ajuster la valeur sur ton échelle ?
    Ou bien la rotation oscille un peu faisant que tu vas pas à 90 mais [89-91] et donc cos oscille aussi.
    Vérifie que ta rotation soit correcte. cos et sin prennent des radians, est-ce que ta rotation est en radian ou en degrès ?
    https://cplusplus.com/reference/cmath/sin/
    Tu pourrais / devrais aussi stocker le vecteur de direction directement plutôt que de recalculer cos & sin chaque fois. Ces fonctions sont lentes.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    Août 2022
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Août 2022
    Messages : 5
    Par défaut
    Tout d'abord bonjour et merci pour vos réponses


    en faite quand je dis que des que sa rotation est environ égal à 0 j'inclue de 359 virgule quelque chose à 0 virgule quelque chose, donc changer l'angle en 360° ne changera rien (j'ai quand même essayé et effectivement ça n'affecte rien du tout).

    ensuite, effectivement ça pouvait marcher (et ce serait logique) de convertir les angles en radian mais malheureusement ça ne fait qu'empirer les choses car le sprite se met à "trembler" (c'est-à-dire qu'il avance et recule en même temps) et c'est la seul ligne qui permet de faire avancer le sprite donc impossible de chercher sur d'autres lignes le problème
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    move(cos(this->getRotation() * 180 / 3.1415927f), sin(this->getRotation() * 180 / 3.1415927f));
    (je met quand même le code ici au cas où)

    oui move accepte les flottants et les parties fractionnaires résiduelles. J'ai essayé ton code je suppose que Rot est égal à RotNew et le résultat est que le sprite avance en cercle autour du point vers lequel il doit normalement avancer (j'espère que j'ai bien expliqué)

    en haut, j'ai une rotation environ égal à 0 et il recule quand il est tourné vers cette orientation (je sais que que l'orientation 0 en trigo est sur la droite, j'aurais du être plus précis). oui il ocsille aussi, c'est pour ça que je dis environ égal (j'aurais encore du être plus précis, décidemment). Je ne savais pas que cos et sin était lent, merci de m'avoir prévenu


    encore merci de m'avoir répondu aussi vite et désolé pour le manque de précisions
    cordialement

  7. #7
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 532
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 532
    Par défaut
    Est-ce que le problème est résolu alors ?

  8. #8
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2018
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juillet 2018
    Messages : 104
    Par défaut
    Citation Envoyé par jaimeBcpLesPizzas Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    move(cos(this->getRotation() * 180 / 3.1415927f), sin(this->getRotation() * 180 / 3.14159276f));
    (je met quand même le code ici au cas où)
    Ben, 1 chance sur 2 (Enfin, pas tout à fait, j'avais précisé PI/180 et pas 180/PI).
    Pour ne pas confondre le sens, il faut te dire que quand getRotation vaut 360°, tu dois envoyer 2pi au cos/sin.

  9. #9
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 633
    Par défaut Angle ou vecteur ?
    Bonjour MoiAussi,

    Citation Envoyé par jaimeBcpLesPizzas Voir le message
    ...J'ai essayé ton code je suppose que Rot est égal à RotNew et le résultat est que le sprite avance en cercle autour du point vers lequel il doit normalement avancer (j'espère que j'ai bien
    expliqué)...
    Donc l'angle n'est pas un angle absolu mais un angle relatif à la direction actuelle du sprite. Je présume que le move(cs, sn) calcule quelque chose comme : vitesse = (v*(cos(a)*cs + sin(a)*sn, v*(sin(a)*cs + cos(a)*sn) où a est l'angle absolu de déplacement courant. En l'absence de changement de direction, cs = 1.0 et sn = 0.0, la vitesse = (v*cos(a), v*sin(a)) reste inchangée. On voit que la moindre erreur (comme le fait que l'angle est lu 2 fois) amplifiée par le module de la vitesse peut induire des écarts plus ou moins importants. Avec un peu de chance la somme en sera nulle et le sprite ira bien là où il doit aller mais avec quelques verres dans le nez.

    Si le move est une fonction sur laquelle tu as la main, j'aurais tendance à travailler directement avec l'angle (move(da) ou peut être mieux turn(da) ) et j'appliquerais un seuil à la variation angulaire pour ramener à 0.0 les valeurs qui en sont très proches (0.0+e, 2*PI-e). L'intérêt de travailler directement avec l'angle est de limiter les calculs et les accumulation d'approximations.
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if(abs(da) > 0.006 ||  abs(da-PIx2) > 0.006) { // Ici seuil  de l'ordre de 0.4°
       a += da;   
       vx = v*cos(a); // utiliser sincos si disponible
       vy = v*sin(a); 
       // ... rotation du sprite d'origine de a
       }
    ...
    Ce code n'est qu'une illustration du principe et ne prétend nullement être applicable tel quel. Il y a par exemple le présupposé que l'angle reste entre -360° et +360°. Par ailleurs; il est vraisemblable que l'angle ne peut varier brutalement comme passer directement à 180° pour un demi tour instantané.

    Salut.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Fonction contrôle de rotation
    Par Dave72 dans le forum Automation
    Réponses: 2
    Dernier message: 27/07/2014, 08h36
  2. [Article] Usage avancé des fonctions JavaScript
    Par Bovino dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 21/12/2011, 00h06
  3. Gauge qui avance en fonction d'un Timer
    Par Alyx² dans le forum Delphi
    Réponses: 10
    Dernier message: 02/03/2007, 14h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo