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

C++ Discussion :

rotation le plus court (rapide) du tank


Sujet :

C++

  1. #1
    Membre confirmé Avatar de ia.jenny
    Profil pro
    Inscrit en
    Août 2007
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 152
    Par défaut rotation le plus court (rapide) du tank
    Bonjour,
    j'ai un problème pour la rotation de mon tank.


    Exemple :
    quand je fais une rotation de position 95° à 188°, là tout va bien.
    Cependant, de 318° à 44°, le programme va décrémenter jusqu'à 44° au lieux incrémenter.


    Si vous pouvez m'aider à résoudre mon problème avec quelque ligne de code pour trouver le chemin le plus rapide quelque soit la valeur de départ et arriver.
    Merci Beaucoup

    int AngStart=318;
    int AngEnd=44;
    Nom : RotationTank.jpg
Affichages : 228
Taille : 412,1 Ko

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 146
    Billets dans le blog
    4
    Par défaut
    Salut,

    peut-on voir ton algo ?
    Il faut découper le problème pour trouver le sens de rotation. Ensuite tu rotates jusqu'à l'angle final.
    Si tu veux continuer dans la direction, tu peux tourner jusque 390°, puis tu fais un %360 pour le rapporter sur [0, 360[.
    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.

  3. #3
    Membre confirmé Avatar de ia.jenny
    Profil pro
    Inscrit en
    Août 2007
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 152
    Par défaut
    pour le moment, c’est ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     if(AngStart<AngEnd) AngStart+=0.5;
    else if(AngStart>AngEnd) AngStart-=0.5;

  4. #4
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 146
    Billets dans le blog
    4
    Par défaut
    Ton algo est trop simple pour le moment.
    Il faut déterminer la direction de la rotation au début de celle-ci.
    Le plus simple dans ce cas est bien souvent de faire des dessins sur ton bureau.
    Par exemple, naïvement et sans support, je dirais
    - si l'angle actuel est < 90 et l'angle voulu est > 270, alors on tourne par la gauche et traverse via 0
    - si on est > 90 et qu'on va sur < 270, alors on tourne vers la droite
    - si on est > 270 et qu'on va < 90, alors on doit tourner par la droite et traverser via 360/0
    - si on est > 270 et qu'on va > 90, alors on tourne par la gauche
    Il y a certainement quelque chose à faire avec de simples opérations et la valeur de 180 de l'angle droit.

    Avec la direction déterminée, tu changes l'angle à chaque frame d'un certain pas jusqu'à atteindre la destination.
    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.

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    D'abord et avant tout, comment gère tu ce qui fait que ton car doit tourner utilises tu des touches (gauche / droite) ou l'axe d'un joystick, ou est-ce "de la pure intelligence artificielle" dans le sens où te rend compte que le char ne va pas tout à fait dans la direction optimale pour atteindre son objectif?

    Car, il n'y a rien à faire: si la nécessité de tourner vient d'une demande de la part de l'utilisateur qu'il demande de tourner à gauche, même si cela occasionne une rotation plus importante que de partir à droite, tu devras te plier au souhait du joueur

    Par contre, si c'est l'intelligence artificielle qui peut se dire "corrige la trajectoire pour atteindre tel azimut", là, tu peux -- effectivement -- considérer que ton char tournera toujours dans se sens demandant la rotation la moins importante possible

    Et, pour commencer, tu dois d'abord et avant tout évaluer le sens de rotation afin de savoir dans quel sens la rotation sera la moins importante.

    Tu ne dois donc pas te baser "simplement" sur la valeur des deux azimuts si tu dois tourner à gauche ou si tu dois -- au contraire -- tourner à droite, mais sur la différence entre les angles que tu devras parcourir dans un sens et dans l'autre.

    Commencons donc par revoir un peu les bases : un tour complet sur soi-même fera toujours 360°, et, si on se base sur les règles de trigonométries, voici comment ils se présentent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
              90°
               |
               |
               |
               |
               |
    180°-------+-------0-360°
               |
               |
               |
               |
               |
             270°
    On peut donc décemment penser que le sens dans lequel le char doit tourner de manière "optimal" présentera toujours une différence d'angle inférieure à 180° et qu'il n'y aura que le cas particulier dans lequel l'azimut à atteindre se trouve exactement dans le dos du char (si le char se trouve dirigé vers l'azimut 180 et qu'il doit se diriger vers l'azimut 0, par exemple) par rapport à son azimut actuel qui permettra de choisir n'importe quel sens pour tourner.

    On peut évaluer, dans un premier temps, la différence d'angle comme correspondant à Delta = AngleMax - AngleMin, où AngleMax correspond à l'azimut le plus important et où AngleMin correspond -- logiquement -- à l'azimute le moins important.

    Seulement, cette valeur (Delta, selon la formule que je donne) présente une sorte de "pivot", dans le sens où, si j'ai AngleMax = 275° et AngleMin = 45°, le résultat que je vais obtenir est de ... 230° (dans le sens horlogique par rapport à AngleMax). Et, comme ce résultat est supérieur à 180° (qui correspond à un demi tour complet), cela signifie que, si je décide de tourner dans le sens anti horlogique, je n'aurai qu'un angle de ... 360° - 230° = ... 130°

    Et ce n'est qu'un fois que tu as compris cela qu'il est temps de s'intéresser à l'azimut représenté par AngleMax.

    Parce que, si AngleMax correspond à l'azimut actuel de ton char, le sens de rotation que tu viens de déterminer est tout à fait valide, alors que, si angleMax correspond à l'azimut à atteindre par ton char, il faudra de nouveau inverser le sens de rotation.

    Autrement dit, la logique que tu devras mettre en place sera proche de celle-ci:

    Primo, nous allons commencer par définir clairement les deux sens de rotations (horlogique et anti horlogique) avec des valeurs inverses, à savoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const int clockWise = -1;
    const counterClockWise = 1;
    Ensuite, nous allons définir les notions de AngleMin et de AngleMax en fonction de la valeur des azimuts et nous en profiterons pour définir un angle de rotation "par défaut":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    auto AngleMin = std::min(AngStart, AngEnd);
    auto AngleMax = std::max(AngStart, AngEnd);
    int Rotation = clockWise;
    J'ai choisi le sens horlogique parce que je vais baser ma logique sur une double hypothèse de travail qui représente une situation "idéale" à mon sens, à savoir que:
    1. l'angle de départ est plus grand que l'angle d'arrivée et que
    2. la différence entre les deux azimuts est inférieure à 180°
    Cette situation idéale n'arrivera peut-être pas toujours. Et peut-être même qu'elle n'arrivera que très rarement, mais bon... Elle va me permettre de simplifier ma logique au maximum.

    En effet, maintenant que j'ai toutes ces données, je peux calculer la différence entre les deux angles
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int Delta = AngleMax - AngleMin;
    Il ne me reste plus qu'à vérifier mes deux hypothèses de travail, et à inverser mon sens de rotation au besoin:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if(Delta >=180°){
        Rotation*=-1; 
        Delta = 360 - Delta;
    }
    if(AngleMax != AngStart){
        Rotation *=-1;
        Delta = 360 - Delta;
    }
    Arrivé à ce stade, le plus dur est fait, car je sais de combien de degrés mon char devra tourner, et je sais dans quel sens il devra le faire. Et, par dessus tout, le nombre de degrés à parcourir sera toujours positif!

    Par facilité, et parce que les angles sont représentés sous forme d'entiers, je vais créer une boucle faisant pivoter le char par tranche de 1°
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    for(int i = 0;i<Delta;++i){
        AngleStart += (1*Rotation);
        /* tout ce qu'il faut faire une fois que le char a effectué une partie de la rotation */
    }
    /* Et parce que je suis un grand stressé, et que j'ai peur de m'être fourvoyé
     * je m'assure que ma logique soit correcte
     */
    assert(AngStart == AngEnd && "bad rotation");
    A priori, ma logique est suffisamment simple que pour être correcte, si bien que l'assertion ne devrait jamais être levée. Mais bon, comme j'ai fait tout cela "à main levée", je peux encore m'être trompé
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre confirmé Avatar de ia.jenny
    Profil pro
    Inscrit en
    Août 2007
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 152
    Par défaut
    merci beaucoup
    ça fonctionne

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

Discussions similaires

  1. Calcul de plus court chemin dans un graphe
    Par Elmilouse dans le forum Prolog
    Réponses: 6
    Dernier message: 21/03/2010, 20h26
  2. [algo] plus courts chemins (au pluriel !!)
    Par ADSL[fx] dans le forum Algorithmes et structures de données
    Réponses: 9
    Dernier message: 18/01/2006, 14h40
  3. néophyte, faire une requête plus courte
    Par LE NEINDRE dans le forum Requêtes
    Réponses: 8
    Dernier message: 10/10/2005, 09h44
  4. algorithme de Ford (recherche chemin le plus court)
    Par abstraite dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 19/05/2005, 10h39
  5. Réponses: 2
    Dernier message: 21/03/2004, 18h57

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