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++Builder Discussion :

Déplacement d'une Cible sur une droite


Sujet :

C++Builder

  1. #1
    Membre confirmé Avatar de kurul1
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    933
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 933
    Points : 466
    Points
    466
    Par défaut Déplacement d'une Cible sur une droite
    Bonjour à tous.

    J'ai une cible à l'écran que je dois déplacer d'un point a un autre sur une ligne droite en suivant sont déplacement. Je connais le point de départ et le point d'arrivée.

    Comment puis-je faire ?

    Merci d'avance

  2. #2
    Membre averti

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Points : 446
    Points
    446
    Par défaut
    Tu veux avancer du point I (initial) à F (final). Coordonnées (Ix,Iy) resp. (Fx,Fy) en un temps donné Ttot. Bien sûr, ce temps peut être en fait un nombre de pas (Si Ttot=1000 pas, alors tu auras T1=1, T2=2, T3=3...).

    Au temps T, la position (X,Y) de la cible est:

    X=Ix+(Fx-Ix)/Ttot*T=Ix+Vx*T (où Vx=(Fx-Ix)/Ttot, la vitesse en X)
    Y=Iy+(Fy-Iy)/Ttot*T=Iy+Vy*T (idem, Vy=(Fy-Iy)*Ttot, la vitesse en Y)

    Si ton temps T est en fait des pas de 1, par exemple, alors tu peux simplement incrémenter la position de Vx et Vy à chaque pas, mais tu as le risque de cumuler une erreur à chaque pas... Le mieux reste de calculer la position à chaque fois:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    TPoint I(Ix,Iy);
    TPoint F(Fx,Fy);
    TPoint pos;
    double Vx=(double)(Fx-Ix)/Ttot;
    double VY=(double)(Fy-Iy)/Ttot;
    for (int t=0;t<1000;++t) {
      pos.x=Vx*t+Ix;
      pos.y=Vy*t+Iy;
    }
    Il faut faire bien attention à calculer la vitesse avec autre chose que des integer, sinon tu as une forte déviation dûe à l'approximation!

    Un exemple d'appli tout bête:
    1) Tu mets ne nombre de pas dans la case "TempsTot"
    2) Tu cliques sur Start
    3) Tu fais un cliquer-glisser depuis le point de départ vers le point d'arrivée


    Le header
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:	// IDE-managed Components
      TEdit *TempsTot;
      TShape *Shape1;
      TBitBtn *BitBtn1;
      TShape *From;
      TShape *To;
      void __fastcall FormMouseDown(TObject *Sender, TMouseButton Button,
              TShiftState Shift, int X, int Y);
      void __fastcall FormMouseUp(TObject *Sender, TMouseButton Button,
              TShiftState Shift, int X, int Y);
      void __fastcall BitBtn1Click(TObject *Sender);
    private:	// User declarations
    public:		// User declarations
      __fastcall TForm1(TComponent* Owner);
     
      bool   ready;  
      TPoint Initial;
      TPoint Final;
      Start();
     
    };
    Le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
      : TForm(Owner)
    {
      ready=false;
     
    }
    //---------------------------------------------------------------------------
     
    void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
     
      if (!ready) return;
      Initial=TPoint(X,Y);  
      From->Left=X;  From->Top=Y;
     
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
     
      if (!ready) return;
      Final=TPoint(X,Y);
      To->Left=X;  To->Top=Y;
      Start();
      ready=false;
     
    }
    //---------------------------------------------------------------------------
     
     
    TForm1::Start()
    {
     
      int Ttot=atoi(TempsTot->Text.c_str());
     
      double Vx=(double)(Final.x-Initial.x)/Ttot;
      double Vy=(double)(Final.y-Initial.y)/Ttot;
     
     
      for (int t=0;t<Ttot;++t) {
        Shape1->Left=Initial.x+Vx*t;
        Shape1->Top=Initial.y+Vy*t;
     
        Shape1->Invalidate();
        Sleep(50);
        Application->ProcessMessages();
     
      }
     
    }
    void __fastcall TForm1::BitBtn1Click(TObject *Sender)
    {
      ready=true;  
    }
    //---------------------------------------------------------------------------
    TPoint

  3. #3
    Membre confirmé Avatar de kurul1
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    933
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 933
    Points : 466
    Points
    466
    Par défaut
    J'ai réussi et je t'en remercie.

    Par contre, j'ai quand même un petit souci, il semblerait que cela ne passe pas exactement sur la ligne droite car j'ai mis un point d'arrêt lorsque mon déplacement s'arrête (teste si le point courant est égal au point final du segment) et cela ne s'arrête pas.

  4. #4
    Membre averti

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Points : 446
    Points
    446
    Par défaut
    En fait, il y a deux choses:
    1) Dans mon code, j'ai fait une erreur dans la boucle: il faut aller de 0 à n et par de 0 à (n-1) pour atteindre le point final
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (int t=0;t<=Ttot;++t)
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (int t=0;t<Ttot;++t)
    2) Avec les arrondis, tu as toujours le risque de te retrouver un tout petit peu à côté de la valeur si tu fais la comparaison en double, mais c'est très improbable si tu compares la position Top/Left et que tu n'utilises pas les incréments: la formule Px=Ix+Vx*t est très précise pour t=Ttot (Px=Ix+(Fx-Ix)/Ttot*Tot=Fx)

    Je pense que ton problème vient de mon erreur (point 1)

  5. #5
    Membre confirmé Avatar de kurul1
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    933
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 933
    Points : 466
    Points
    466
    Par défaut
    Voilà moi comment j'ai fait

    Unit1.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    //---------------------------------------------------------------------------
     
    #ifndef Unit1H
    #define Unit1H
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <Menus.hpp>
    #include <ExtCtrls.hpp>
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:	// Composants gérés par l'EDI
            TPopupMenu *PopupMenu;
            TMenuItem *Quitter;
            TMenuItem *LancerLeMouvement;
            TTimer *Timer;
            void __fastcall QuitterClick(TObject *Sender);
            void __fastcall OnPaint(TObject *Sender);
            void __fastcall LancerLeMouvementClick(TObject *Sender);
            void __fastcall OnTimer(TObject *Sender);
    private:	// Déclarations de l'utilisateur
    public:		// Déclarations de l'utilisateur
            // Variables
            bool Mouvement;         // booléen pour le mode mouvement
     
            POINT Pts[3];           // tableau des centres de cibles
     
            POINT Point;            // Point courant
     
            int NumSegment;         // Numéro du segment courant
     
            double Vitesse;         // Vitesse du mouvement
     
            double Temps;           // Temps pour réaliser le déplacement
     
            double VX, VY;          // Vitesse sur le segment
     
            // Temps de début de cible
            __int64 TpsDbtCible;
     
            // Fréquence de l'horloge
            __int64 FreqHorloge;
     
            // Méthodes
            __fastcall TForm1(TComponent* Owner);
     
            // Méthode qui calcule le temps pour le segment
            double TempsSegment(int Num);
     
            // Méthode qui permet de calculer la longueur du segment
            double LongueurSegment(int Num);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    Unit1.cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
     
    //---------------------------------------------------------------------------
     
    #include <vcl.h>
    #pragma hdrstop
     
    #include "Unit1.h"
    #include <math.h>
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
            // On initialise les dimensions de la zone client
            Form1->ClientWidth = Screen->Width;
            Form1->ClientHeight = Screen->Height;
     
            // On positionne la form
            Form1->Top = 0;
            Form1->Left = 0;
     
            // On initialise le tableau des points
            Pts[0].x = 70;
            Pts[0].y = 70;
     
            Pts[1].x = ClientWidth / 2;
            Pts[1].y = ClientHeight / 2;
     
            Pts[2].x = ClientWidth - 70;
            Pts[2].y = ClientHeight - 710;
     
            // On calcule la fréquence de l'horloge
            QueryPerformanceFrequency((LARGE_INTEGER*)&FreqHorloge);
    }
    //---------------------------------------------------------------------------
     
    // Méthode qui permet de quitter l'application
    void __fastcall TForm1::QuitterClick(TObject *Sender)
    {
            Application->Terminate();
    }
    //---------------------------------------------------------------------------
    // Méthode qui dessine l'écran
    void __fastcall TForm1::OnPaint(TObject *Sender)
    {
            int x1, x2, y1, y2;
     
     
            // Si l'on est en mode mouvement
            if(Mouvement)
            {
                    // On dessine l'arrière-plan
                    Canvas->Pen->Color = clWhite;
                    Canvas->Brush->Color = clWhite;
                    Canvas->Rectangle(0, 0, ClientWidth, ClientHeight);
     
                    // On affiche la cible courante
                    x1 = Point.x - 30;
                    y1 = Point.y - 30;
                    x2 = x1 + 60;
                    y2 = y1 + 60;
     
                    Canvas->Pen->Color = clRed;
                    Canvas->Brush->Color = clRed;
                    Canvas->Ellipse(x1, y1, x2, y2);
     
     
                    // Première cible
                    x1 = Pts[0].x - 30;
                    y1 = Pts[0].y - 30;
                    x2 = x1 + 60;
                    y2 = y1 + 60;
     
                    Canvas->Pen->Color = clBlue;
                    Canvas->Brush->Color = clBlue;
                    Canvas->Ellipse(x1, y1, x2, y2);
     
     
                    // Deuxième cible
                    x1 = Pts[1].x - 30;
                    y1 = Pts[1].y - 30;
                    x2 = x1 + 60;
                    y2 = y1 + 60;
     
                    Canvas->Pen->Color = clGreen;
                    Canvas->Brush->Color = clGreen;
                    Canvas->Ellipse(x1, y1, x2, y2);
     
     
                    // Troisième cible
                    x1 = Pts[2].x - 30;
                    y1 = Pts[2].y - 30;
                    x2 = x1 + 60;
                    y2 = y1 + 60;
     
                    Canvas->Pen->Color = clYellow;
                    Canvas->Brush->Color = clYellow;
                    Canvas->Ellipse(x1, y1, x2, y2);
            }
            // Sinon
            else
            {
                    // On efface l'écran
                    Canvas->Pen->Color = clAppWorkSpace;
                    Canvas->Brush->Color = clAppWorkSpace;
                    Canvas->Rectangle(0, 0, ClientWidth, ClientHeight);
            }
    }
    //---------------------------------------------------------------------------
    // Méthode qui lance le mouvement
    void __fastcall TForm1::LancerLeMouvementClick(TObject *Sender)
    {
            // On met le booléen de mouvement à true
            Mouvement = true;
     
            // On se positionne sur le premier segment
            NumSegment = 0;
     
            // On initialise la vitesse du mouvement
            Vitesse = 50;
     
            // On positionne le point courant sur le première cible
            Point.x = Pts[NumSegment].x;
            Point.y = Pts[NumSegment].y;
     
            // On calcule le temps pour effectué le déplacement complet
            Temps = TempsSegment(NumSegment);
     
            // On calcule la vitesse sur le segment en x et en y
            VX = double(Pts[NumSegment + 1].x - Pts[NumSegment].x) / Temps;
            VY = double(Pts[NumSegment + 1].y - Pts[NumSegment].y) / Temps;
     
            // On configure le timer
            Timer->Interval = 10;
     
            // On lance le timer
            Timer->Enabled = true;
     
            // On calcule le temps au début de la cible
            QueryPerformanceCounter((LARGE_INTEGER*)&TpsDbtCible);
     
            // On dessine l'écran
            OnPaint(Form1);
    }
    //---------------------------------------------------------------------------
    // Méthode qui calcule le temps pour le segment
    double TForm1::TempsSegment(int Num)
    {
            return LongueurSegment(Num) / Vitesse;
    }
     
    //---------------------------------------------------------------------------
     
    // Méthode qui permet de calculer la longueur du segment
    double TForm1::LongueurSegment(int Num)
    {
            double opx, opy;
     
            opx = (Pts[Num + 1].x - Pts[Num].x) * (Pts[Num + 1].x - Pts[Num].x);
            opx = (Pts[Num + 1].y - Pts[Num].y) * (Pts[Num + 1].y - Pts[Num].y);
     
            return sqrt(opx + opy);
    }
     
    //---------------------------------------------------------------------------
    // Méthode déclancher à la fin du timer
    void __fastcall TForm1::OnTimer(TObject *Sender)
    {
            // Temps courant
            __int64 TpsCourant;
     
            // Temps pour le calcul
            double T;
     
            // Si l'on a parcourut tous les segments
            if(NumSegment == 2)
            {
                    // On arrête le timer
                    Timer->Enabled = false;
     
                    // On met le booléen du mode mouvement à faux
                    Mouvement = false;
     
                    ShowMessage("Fin");
            }
            // Sinon
            else
            {
                    if((Point.x == Pts[NumSegment + 1].x) && (Point.y == Pts[NumSegment + 1].y))
                    {
                            // On passe au segment suivant
                            NumSegment++;
     
                            //ShowMessage("On passe au segment suivant");
     
                            // On positionne le point sur le début du segment
                            Point.x = Pts[NumSegment].x;
                            Point.y = Pts[NumSegment].y;
     
                            // On calcule le temps pour effectué le déplacement complèt
                            Temps = TempsSegment(NumSegment);
     
                            // On calcule la vitesse sur le segment en x et en y
                            VX = double(Pts[NumSegment + 1].x - Pts[NumSegment].x) / Temps;
                            VY = double(Pts[NumSegment + 1].y - Pts[NumSegment].y) / Temps;
     
                            // On calcule le temps au début de la cible
                            QueryPerformanceCounter((LARGE_INTEGER*)&TpsDbtCible);
                    }
                    else
                    {
                            // On mesure le temps courant
                            QueryPerformanceCounter((LARGE_INTEGER*)&TpsCourant);
     
                            // On calcule le temps du point
                            T = (TpsCourant - TpsDbtCible)/(double)FreqHorloge;
     
                            Point.x = (VX * T) + Pts[NumSegment].x;
                            Point.y = (VY * T) + Pts[NumSegment].y;
                    }
     
                    // On appel la méthode de dessin
                    OnPaint(Form1);
            }
     
    }
    //---------------------------------------------------------------------------

  6. #6
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 374
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    Il faut juste arrondir avec un peu plus de précision :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int arrondir(double *D)
    {
    return (*D + (*D - floor(*D)));
    }
    Je ne sais pas s'il y a plus simple !

    A plus !

  7. #7
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Point.x = (VX * T) + Pts[NumSegment].x;
    Point.y = (VY * T) + Pts[NumSegment].y;
    Remarque :Un petit inconvénient de ce calcul, mais peut être que dans ton appli ça n'a pas d'importance, est que ta cible peut se déplacer par bonds (ou au contraire stagner à un endroit, ce qui fait du calcul pour rien). Elle peut sauter des positions sur la ligne droite. Dans son déplacement, il peut y avoir des emplacements sur la droite où elle ne se trouvera jamais. Si c'est grave, il faut modifier l'algo de calcul des points de la droite
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  8. #8
    Membre averti

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Points : 446
    Points
    446
    Par défaut
    Le problème vient du fait que tu maîtrises mal le temps écoulé dans le soft. Celui-ci est en double et le timer n'est pas forcement d'une très grande précision. Résultat, tu tombes rarement juste dans les points calculés et finaux.

    Le mieux est de calculer si tu as atteint ou dépassé la cible d'arrivée et de t'intérrompre à ce moment-là. Pour celà, tu peux soit calculer le temps total écoulé et voir si tu as dépassés ton Temps prévu, mais le plus élégant, c'est de jouer avec les vecteurs pour voir quand ton point P est passé derrière le point F (final). Je te propose de remplacer ton test

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if((Point.x == Pts[NumSegment + 1].x) && (Point.y == Pts[NumSegment + 1].y))
    par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
                    // On s'arrête dès qu'on a dépassé le point d'arrivée,càd quand
                    // le vecteur P--F est dans le sens inverse que I--F. On calcule
                    // ça comme le produit scalaire entre (IF) et (PF) qui devient
                    // négatif lorsque les vecteurs sont de sens opposés
                    //       ProduitScalaire(<Ax,Ay>,<Bx,By>)=Ax*Bx+Ay+By
                    //
                    // Nous calculons P--F et I--F:
                    //   PF=F-P=<Fx-Px,Fy-Py>
                    //   IF=F-I=<Ix-Fx,Iy-Fy>
                    //
                    // Dans ton implémentation:
                    //   P=Point,
                    //   F=Pts[NumSegment+1]
                    //   I=Pts[NumSegment]
                    //
                    // Ce qui donne:
                    //   ProduitScalaire=(Fx-Px)*(Fx-Ix)+(Fy-Py)*(Fy-Iy)
                    //       =(Pts[NumSegment+1].x-Point.x)*(Pts[NumSegment+1].x-Pts[NumSegment].x)
                    //         +(Pts[NumSegment+1].y-Point.y)*(Pts[NumSegment+1].y-Pts[NumSegment].y)
                    if( (Pts[NumSegment+1].x-Point.x)*(Pts[NumSegment+1].x-Pts[NumSegment].x)
                       +(Pts[NumSegment+1].y-Point.y)*(Pts[NumSegment+1].y-Pts[NumSegment].y)<=0)
    Le principe est qu'en géométrie vectorielle, le produit scalaire entre deux vecteurs donne la projection de l'un sur l'autre. Lorsqu'ils sont perpendiculaires le produit scalaire est nul, lorsqu'ils sont dans le même sens, il est positif, et lorsqu'ils sont opposé il est négatif.

    Si tu calcules les vecteurs I-->F et P-->F (P=point courant, I=point initial, F=point final), tu peux ainsi savoir si P a dépassé F car (I-->F)*(P-->F) devient négatif.

    Demande-moi si tu veux plus d'explications... Mais le code a l'air de fonctionner!

    Il me semble qu'il y a un truc bizarre avec ta vitesse qui n'est pas identique entre les 2 segments, mais je ne trouve pas de faute...

  9. #9
    Membre averti

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Points : 446
    Points
    446
    Par défaut
    Le produit scalaire était mal écrit dans mon commentaire. Il faut lire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    //       ProduitScalaire(<Ax,Ay>,<Bx,By>)=Ax*Bx+Ay*By

  10. #10
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 374
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    La progression de la cible se calcule aussi simplement par progression de n points
    par intervalle de temps sur la droite reliant les deux points (départ et arrivée).

    On a juste, au départ, à calculer une distance, un sinus et un cosinus.
    Ici j'utilise :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    TPoint *arrivee;
    TPoint *depart;
    double distance, sinus, cosinus, progression, pas;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    double dx = arrivee->x - depart->x;
    double dy = arrivee->y - depart->y;
    distance = hypot(dx, dy);
    sinus = 0; cosinus = 0;
    if(distance != 0)
        {
        sinus = dy / distance;
        cosinus = dx / distance;
        }
    x = depart->x;
    y = depart->y;
    progression = 0;

    La position de la cible en mouvement sur la droite se calcule à l'aide de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    progression = progression + pas;
    si progression < distance
        x = (cosinus * progression) + depart->x;
        y = (sinus * progression) + depart->y;
    sinon
        x = arrivee->x;
        y = arrivee->y;
    A plus !

  11. #11
    Membre confirmé Avatar de kurul1
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    933
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 933
    Points : 466
    Points
    466
    Par défaut
    Merci à toi henderson, je vais regarder ça

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

Discussions similaires

  1. [WD18] Metre une colonne d'une Table sur une ligne d'une autre Table
    Par Totophe2 dans le forum WinDev
    Réponses: 2
    Dernier message: 22/11/2013, 12h58
  2. afficher une valeur sur une feuille lorsqu'une checkbox est cochée
    Par chrnoe dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 23/12/2008, 14h39
  3. probleme avec l'appui sur une touche sur une jframe ou jdialog
    Par jeanfeu dans le forum Agents de placement/Fenêtres
    Réponses: 1
    Dernier message: 05/08/2008, 16h14
  4. [VBA Excel] Appliquer une macro sur une celulle contenant une valeur
    Par tchauviere dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 21/01/2008, 10h21
  5. Réponses: 3
    Dernier message: 16/01/2006, 16h02

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