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

 

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2014
    Messages
    367
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2014
    Messages : 367
    Points : 87
    Points
    87

    Par défaut Algorithme de déplacement : calculer un angle

    Bonjour,

    J'ai besoin de faire en sorte qu'un objet fixe soit toujours tourné vers un point mobile, sur un plan orthonormé (2D).

    J'utilise donc la fonction tan ex :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    angle = (Math.tan((World.x - Objet.x) / (World.y-Objet.y))*(180/Math.PI));
    Cela fonctionne cependant je suis obligé de mettre des conditions lorsque une valeur ou l'autre est inférieur...Du coup je bricole un peu la chose par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       if ( Math.abs(Game.x - x) < Math.abs(Game.y - y) ){
                if ( Game.y - y > 0 ){
                    d = (Math.tan((Game.x - x) / (Game.y-y))*(180f/(float)Math.PI))-90f;
                }else{
                    d = (Math.tan((Game.x - x) / (Game.y-y))*(180f/(float)Math.PI))+90f;
                }
            }
    Déjà j'aime pas ce genre de bricolage est il vraiment nécessaire ou connaissez vous une façon plus simple pour obtenir le résultat sans mettre 36000 conditions ?

    En plus, lorsque j'arrive sur les bords l'angle qui en résulte devient légèrement plus grand ce qui fait une saccade quand on passe de l'un à l'autre.

    Merci si vous pouvez m'aider.

  2. #2
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    août 2008
    Messages
    23 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : août 2008
    Messages : 23 470
    Points : 144 019
    Points
    144 019

    Par défaut



    A priori, la fonction atan2 (à deux arguments, pour éviter la division et la perte d'informations corre) sert à résoudre ce genre de problèmes.
    https://nl.mathworks.com/help/matlab/ref/atan2.html
    http://www.cplusplus.com/reference/cmath/atan2/
    Vous souhaitez participer aux rubriques Qt ou PyQt (tutoriels, FAQ, traductions), HPC ? Contactez-moi par MP.

    Créer des applications graphiques en Python avec PyQt5
    Créer des applications avec Qt 5.

    Pas de question d'ordre technique par MP !

  3. #3
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2014
    Messages
    367
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2014
    Messages : 367
    Points : 87
    Points
    87

    Par défaut

    dourouc05 Génial, merci il semblerait que ça marche!

  4. #4
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2014
    Messages
    367
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2014
    Messages : 367
    Points : 87
    Points
    87

    Par défaut

    Heu une dernière chose.

    En fait maintenant que j'ai trouvé l'angle j'aimerais le transformer en longueur et largeur pour faire avancer mon objet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            cap = Math.atan2((Game.x - x),(Game.y-y));
            setPosition(x - Game.x, Game.y - y, (float) (cap* (180 / Math.PI))-90); //je dessine l'angle 
    
            x += Math.cos(cap)* ((Game.gameTime()-time)/5000000000f)
            y += Math.sin(cap)* ((Game.gameTime()-time)/5000000000f)
    Le problème est que mon objet se déplace bien dans l'axe...mais à l'envers. J'ai beau essayé de soustraire au lieu d'ajouter, de mettre un Radian avec PI en plus pour faire 180) il inverse toujours la trajectoire.
    -ou un coup il se rapproche puis après il inverse et s'éloigne...

  5. #5
    Membre éprouvé
    Homme Profil pro
    F5(){F5}
    Inscrit en
    avril 2008
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : F5(){F5}
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : avril 2008
    Messages : 623
    Points : 979
    Points
    979

    Par défaut

    sans contexte (ni définition de tes variables) c'est pas facile de comprendre ce que tu fais... ni pourquoi ca marche pas.

    en revanche, si tu calcules un angle pour...ensuite le repasser en vecteur ptet que ya un pb.

    quand A et B sont deux points... pour que A regardes B il suffit que A regarde dans le sens du vecteur AB...
    si A=(x, y) et B=(Game.x, Game.y)
    trivialement, le vecteur pour regarder vers B est... v=B-A=(Game.x-x, Game.y-y)
    si tu veux te déplacer vers B depuis A... tu normes ton vecteur
    v_u = v/norme(v) et
    dv=v_u*((Game.gameTime()-time)/5000000000f)
    trivialement
    x += dv[0]
    y += dv[1]

    et tu finiras par te rapprocher de B

  6. #6
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2014
    Messages
    367
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2014
    Messages : 367
    Points : 87
    Points
    87

    Par défaut

    Oui, en effet, ça marche.

    Cependant j'aimerais calculer l'avancée x et y en fonction d'un angle et non du vecteur...car cela me permettra de gérer une trajectoire moins brutale : ex l'objet avance et suit un angle qui va toujours chercher à être le plus proche de l'angle qui le mène vers sa cible.
    EX :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if ( angleDeDirrection < angleDeLaCible ){
           angleDeDirrection = Math.min(angleDeLaCible, angleDeDirrection + vitesseDeChangementDAngle);
    }else{
           angleDeDirrection = Math.max(angleDeLaCible, angleDeDirrection - vitesseDeChangementDAngle);
    }
    du coup si la cible bouge par exemple, l'objet qui va vers lui risque de passer à côté ce qui est voulu...selon le déplacement d'ailleurs, si l'angle reste à peut près le même entre les 2 objets il finiront par se heurter.

  7. #7
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    décembre 2013
    Messages
    1 957
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : décembre 2013
    Messages : 1 957
    Points : 4 078
    Points
    4 078

    Par défaut

    De manière générale, les tests si angle1 < angle2 , ça ne marche jamais.
    En effet, 0° ou 360°, c'est la même direction. Donc 120° est-il plus grand que 0°, ou plus petit que 360°, on ne sait pas.

    Par ailleurs, il te manque plein de choses. Tu parles de angleDirection et AngleCible. Ok. Admettons que la Cible va vers le haut de l'écran, et le joueur aussi va vers le haut de l'écran. Dans ta formule, tu utilises uniquement ces 2 inputs. Mais la position d'origine de la cible et du joueur doivent être prises en compte. Si le joueur est sur la partie droite de l'écran, ou s'il est à gauche, ou s'il est en bas, on veut que la fonction donne 3 réponses différentes. Or, ta fonction ne prend pas en compte la position du joueur !
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  8. #8
    Membre expérimenté

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    décembre 2010
    Messages
    672
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2010
    Messages : 672
    Points : 1 344
    Points
    1 344
    Billets dans le blog
    5

    Par défaut Algorithme de déplacement : calculer un angle

    Bonjour,

    Si c'est un problème de poursuite, le chasseur (A) se déplace constamment vers la position actuelle de la la cible (B), indépendamment du déplacement simultané de cette dernière.

    En notant (r) la distance séparant les positions courantes des deux points
    r = ((xB - xA)2 + (yB - yA)2)1/2
    le déplacement de (A) dans l'intervalle de temps (DeltaT) considéré est représenté par le vecteur
    DeltaA = (VA*DeltaT/r).((xB - xA).Ux + (yB - yA).Uy) .

    (B) sera rattrapé dès lors qu'il se déplace à une vitesse plus faible: VB < VA .

    Si l'on s'intéresse au changement de l'orientation du tir, il suffit de considérer les valeurs successives du vecteur (AB) à deux instants consécutifs:
    P = AB(t)
    P1 = AB(t + DeltaT) = P + DeltaT.(VB - VA)
    puis de calculer le déterminant correspondant:
    Det(P, P1) = (P, P1, Uz) = (P*P1)*Sin(u)
    qui s'exprime en fonction de l'écart angulaire entre les deux vecteurs:
    u = (P, P1) = Arcsin(Det(P, P1)/(P*P1)) .


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  9. #9
    Membre éprouvé
    Homme Profil pro
    F5(){F5}
    Inscrit en
    avril 2008
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : F5(){F5}
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : avril 2008
    Messages : 623
    Points : 979
    Points
    979

    Par défaut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    l'objet qui va vers lui risque de passer à côté ce qui est voulu...
    ok

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     cap = Math.atan2((Game.x - x),(Game.y-y));
            setPosition(x - Game.x, Game.y - y, (float) (cap* (180 / Math.PI))-90); //je dessine l'angle 
    
            x += Math.cos(cap)* ((Game.gameTime()-time)/5000000000f)
            y += Math.sin(cap)* ((Game.gameTime()-time)/5000000000f)

    note par rapport à ton code
    ca a l'air detre en js.
    si tu regardes le proto de atan2
    https://developer.mozilla.org/en-US/...cts/Math/atan2

    atan2 s'attend à avoir Math.atan2(y,x) et non Math.atan2(x,y)

    Par ailleurs ton setPosition est mauvais:
    setPosition(x-Game.x, Game-y) ----> setPosition(Game.x-x, Game-y)

    (cap* (180 / Math.PI))-90
    ca ressemble __très fortement__ à une symétrie par rapport à l'axe x=y que tu as du bidouiller (en plus de ton x-Game.x lol)?? parce que atan2(x,y) correspond à un angle dont les coordonnées ont été interverties (==symétrie par rapport à axe y=x)

    et ca ne devrait pas être necessaire, simplement cap en paramètre devrait suffire

    Attention encore une fois
    angleDeDirrection + vitesseDeChangementDAngle
    un angle c'est un angle, une vitesse c'est pas un angle.
    Donc si c'est vraiment une vitesse, c'est vitesseDeChangementDAngle*deltaT
    sinon tu l'appel deltaAngle...

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

Discussions similaires

  1. algorithme pour le calcul d'une integrale double
    Par awalle dans le forum Mathématiques
    Réponses: 5
    Dernier message: 04/05/2007, 09h35
  2. Calcul d'angles
    Par Giansolo dans le forum Octave
    Réponses: 3
    Dernier message: 27/02/2007, 19h00
  3. calcule d'angle entre 3 points d'une matrice
    Par bmw13fr dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 08/04/2006, 18h56
  4. Algorithme permettant de calculer le PGCD de deux nombres
    Par zeyd dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 25/11/2005, 20h37
  5. calculer un angle
    Par m.nico dans le forum Langage
    Réponses: 7
    Dernier message: 05/11/2003, 20h55

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