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

Mathématiques Discussion :

Le bout d'une barbe ou comment dessiner une flèche


Sujet :

Mathématiques

  1. #1
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut Le bout d'une barbe ou comment dessiner une flèche
    Pour trouver une solution d'un exercice de l'excellent livre récent de Stroustrup Programming, Principles and practise using C++, il me manque un peu de géométrie/trigonométrie.
    Il s'agit de l'exercice 3 du chapitre 13 :
    Define a class Arrow, which draws a line with an arrowhead.
    exercice proposé, dans le cadre de FLTK et de tous les éléments introduits par l'auteur dans les chapitres 12 et 13 de l'ouvrage.
    La question purement mathématique que je voudrais résoudre pour pouvoir implémenter la chose est la suivante :
    Connaissant :
    - les coordonnées x0,y0 du point A, queue de la flèche
    - les coordonnées x1, y1 du point B, tête de la flèche
    - la longueur d de chacune des deux barbes
    - l'angle aigu alpha de chaque barbe avec le corps de la flèche :

    comment calculer les coordonnées des extrémités M et M' de chacune des deux barbes BM et BM' (et ceci quelle que soit la pente de la flèche, que je ne suppose donc pas nécessairement horizontale ou verticale) ?

  2. #2
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Pour clarifier :


  3. #3
    Membre habitué Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Points : 190
    Points
    190
    Par défaut
    Le plus simple (à mon sens) est de te définir un repère local (O,i,j) à la flèche.
    La base O est en A, i est le vecteur AB et j est à calculer comme un vecteur perpendiculaire à i.
    De mémoire : Un fois que tu as ça, tout devient simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    M  = 0.8i + 0.2j
    M' = 0.8i - 0.2j
    (j'ai pris 0.8 et 0.2 à la louche en regardant ton schéma)

    Si les notions de repère et de calcul vectoriel sont un peu confuses, cherche un peu autour de toi, et si ça ne t'avance toujours pas, reviens ici...

  4. #4
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Humpff... Merci, je vais regarder ton message à tête reposée...

    Ce qui m'intéresse, c'est une formule qui me permette de calculer (de faire calculer par le programme) les coordonnées - par rapport au repère Ox, Oy de mon dessin - des points M et M', en fonction des coordonnées de A et de B (par rapport au même repère) supposées connues, de la longueur BM = BM' = d supposée connue et de l'angle alpha = MBA = M'BA supposé connu lui aussi...

  5. #5
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 949
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 949
    Points : 5 665
    Points
    5 665
    Par défaut
    Bao,

    C'est de la géométrie élémentaire.

  6. #6
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par droggo Voir le message
    C'est de la géométrie élémentaire.
    Elémentaire peut être mais j'avoue avec une certaine honte que je me suis penché sur le problème et que je n'ai pas réussi à sortir une solution (que je sais simple). Mes souvenir ne veulent par remonter ...

  7. #7
    Membre habitué Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Points : 190
    Points
    190
    Par défaut
    On a en entrée Ax, Ay, Bx et By, et on veut calculer M1x, M1y, M2x et M2y.
    (ça va jusque là ?)

    On définit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Ix = Bx - Ax
    Iy = By - Ay
    Jx = Iy
    Jy = -Ix
    et il vient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    M1x = Ax + 0.8*Ix + 0.2*Jx
    M1y = Ay + 0.8*Iy + 0.2*Jy
    M2x = Ax + 0.8*Ix - 0.2*Jx
    M2y = Ay + 0.8*Iy - 0.2*Jy
    et voilà...

    (je ne l'ai pas codé et pas testé, mais ça devrait être bon)

  8. #8
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Merci pour ces compléments.
    Citation Envoyé par sopsag Voir le message
    On a en entrée Ax, Ay, Bx et By, et on veut calculer M1x, M1y, M2x et M2y.
    (ça va jusque là ?)
    On a en entrée Ax, Ay, Bx, By ET la distance d ainsi que l'angle alpha, sans d et alpha M et M' ne seront pas déterminés.

    Pourrais-tu expliciter ce que représentent tes 0.8 et 0.2 ?

  9. #9
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 43
    Points : 34
    Points
    34
    Par défaut
    Bonjour,

    Pour la partie géométrie (y'a surement moyen de simplifier encore):

    il nous faut l'angle Beta que fait le vecteur AB avec l'axe X:

    Beta=Arctan((Yb-Ya)/(Xb-Xa))
    On pose:
    Alpha1=Alpha - Beta
    Alpha2=Alpha-((PI/2)-Beta)

    Ensuite 4 cas possible (bien sur on ne fait rien si Xa=Xb et Ya=Yb ^^):
    Xb>Xa (cela inclus le cas ou Yb=Ya)
    Mx=-d*COS(Alpha1)+Xb
    My=d*SIN(Alpha1)+Yb
    M'x=d*SIN(Alpha2)+Xb
    M'y=-d*COS(Alpha2)+Yb

    Xb<Xa (cela inclus le cas ou Yb=Ya)
    Mx=d*COS(Alpha1)+Xb
    My=-d*SIN(Alpha1)+Yb
    M'x=-d*SIN(Alpha2)+Xb
    M'y=d*COS(Alpha2)+Yb

    Yb>Ya et Xa=Xb (Arctan infinie pour Beta=+/- Pi/2):
    Mx=-d*SIN(Alpha)+Xb(=Xa)
    My=-d*COS(Alpha)+Yb
    M'x=d*SIN(Alpha)+Xb(=Xa)
    M'y=-d*COS(Alpha)+Yb

    Yb<Ya et Xa=Xb (Arctan infinie pour Beta=+/- Pi/2):
    Mx=-d*SIN(Alpha)+Xb(=Xa)
    My=d*COS(Alpha)+Yb
    M'x=d*SIN(Alpha)+Xb(=Xa)
    M'y=d*COS(Alpha)+Yb

    Tu peut verifier ces formules mais cela devrait fonctionner.

    Coté programmation:
    C'est pas mon fort mais en identifiant bien les cas possible et avec une librairie mathématique (ou des templates) cela doit etre possible.

    Cordialement.
    Darki03

    EDIT: Petite corrections dans les deux cas Xa=Xb => c'est alpha partout ! Je rajoute un petit fichier excel de test rapide (si tu voit pas comment il fonctionne demande moi)
    Fichiers attachés Fichiers attachés

  10. #10
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Aaah... voilà... de la bonne géométrie élémentaire, comme disait l'autre, à se mettre sous la dent... juste ce qu'il me fallait... vais regarder ça de très près et vous tiendrai au courant... merci beaucoup !!
    EDIT et merci aussi pour le fichier joint !

  11. #11
    Membre habitué Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Points : 190
    Points
    190
    Par défaut
    Ok, pour intégrer d et alpha plus facilement, il vaut mieux se mettre dans le repère centré en B tel que i = BA :
    On intriduit le vecteur D = BM
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Ix = Ax - Bx
    Iy = Ay - By
    Jx = Iy
    Jy = -Ix
    Dx = d*cos( alpha )
    Dy = d*sin( alpha )
     
    M1x = Bx + Dx*Ix - Dy*Jx
    M1y = By + Dx*Iy - Dy*Jy
    M2x = Bx + Dx*Ix + Dy*Jx
    M2y = By + Dx*Iy + Dy*Jy
    et voilà...
    Les valeurs ( 0.8 , 0.2 ) était le veteur D évalué à la louche d'après ton schéma (comme dit dans mon premier post)

  12. #12
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    @Darki03 :
    Je viens de vérifier toutes les formules dans un premier petit programme d'essai. ça
    marche apparemment très bien. Me reste plus qu'à implémenter la classe Arrow demandée dans l'exercice de Stroustrup. Donnerai le détail ici quand j'aurai eu le temps de terminer.

  13. #13
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 43
    Points : 34
    Points
    34
    Par défaut
    Je viens aussi de penser aux matrices de passage mais il faudrait que je teste car c'est des lointains souvenirs ! Si j'ai le temps j'essairai. Cela permettrai d'utiliser les formules de Sopsag dans un repere basé sur le vecteur AB et d'utiliser la matrice de passage pour revenir dans le repère initial.

    En tout cas content d'avoir aidé (si je peut voir l'implémentation de ta classe pour ma culture informatique personnelle je t'en serait reconnaissant )

  14. #14
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 43
    Points : 34
    Points
    34
    Par défaut
    Rohh la honte y'a beaucoup plus simple => la méthode de sopsag (il a utilisé une matrice de passage).

    Par contre si je ne trompe pas il faut normaliser le repère basé sur le vecteur BA:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Ix = (Ax - Bx)/norme(BA)
    Iy = (Ay - By)/norme(BA)
    Jx = Iy
    Jy = -Ix
    Dx = d*cos( alpha )
    Dy = d*sin( alpha )
     
    M1x = Bx + Dx*Ix - Dy*Jx
    M1y = By + Dx*Iy - Dy*Jy
    M2x = Bx + Dx*Ix + Dy*Jx
    M2y = By + Dx*Iy + Dy*Jy
    Je joint un autre fichier pour exemple.
    Désolé Sopsag ! journée fatiguante
    Fichiers attachés Fichiers attachés

  15. #15
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Voici donc la réponse que je peux proposer pour l'exercice 3 du chapitre 13 de l'ouvrage de Stroustrup Programming, Principles and Practise Using C++ paru en janvier 2009 :
    Define a class Arrow, which draws a line with an arrowhead.
    J'utilise pour l'instant la (première) méthode de Darki03. Encore merci à lui.

    Je regarderai plus tard la méthode de sopsag (il devrait suffire de reformuler la fonction barbs_ends()).

    Attention : la réponse ne prend son sens que dans le cadre des chapitres 12, 13 et 14 du livre et peut surtout intéresser ceux d'entre vous qui l'ont sous la main et l'utilisent, en en faisant tous les exercices (ce qui est certainement la chose à recommander).

    La classe proposée utilise une classe de base Shape décrite dans le chapitre 14 du livre (en 14.2) et utilise la librairie graphique FLTK (fonction fl_line).
    Toutes remarques critiques bienvenues...

    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
    //----------------------------------------------------------------------------
     
    class Arrow : public Shape {
      public:
        Arrow(Point from, Point to); // from = queue de la flèche, to = pointe de la flèche
        Arrow(Point from, Point to, int barb_length, double barb_angle); // barb__length = longueur de la barbe
    						      // barb_angle = angle de la barbe avec le corps de la flèche
     
        void draw_lines() const; // dessine la flèche sur l'écran
     
        int barb_length() const { return d; }
        void set_barb_length(int dd)  { d = dd; }
     
        double barb_angle() { return Alpha;}
        void set_barb_angle(double a) { Alpha = a;}
     
      private:
          int d; // longueur de chacune des barbes de la flèche
          double Alpha; // angle aigu de chaque barbe avec le corps de la flèche, exprimé en radians
          void barbs_ends(); // calcule les coordonnées des extrémités des barbes 
    			 // et les place en point(2) et point(3) (cf. Shape)
    };
     
    //----------------------------------------------------------------------------
     
    Arrow::Arrow(Point from, Point to) : d(20), Alpha(0.35)
    {
      if (from.x == to.x && from.y == to.y )
        error("Flèche nulle");
      add(from);
      add(to);
      barbs_ends(); // calcule les coordonnées des extrémités des barbes et les place en point(2) et point(3)
    }
     
    //----------------------------------------------------------------------------
     
    Arrow::Arrow(Point from, Point to, int barb_length, double barb_angle):  d(barb_length), Alpha(barb_angle)
    {
     
      if (from.x == to.x && from.y == to.y )
        error("Flèche nulle");
      if ( d <= 0 || Alpha <= 0 ) 
        error("Flèche imberbe");
      add(from);
      add(to);
      barbs_ends(); // calcule les coordonnées des extrémités des barbes et les place en point(2) et point(3)
    }
     
    //----------------------------------------------------------------------------
     
    void Arrow::draw_lines() const
    {
      // point(0) = queue de la flèche, point(1) = tête de la flèche
      if(color().visibility()) {
        fl_line(point(0).x,point(0).y, point(1).x, point(1).y); // tracé du corps de la flèche
     
        fl_line(point(1).x, point(1).y, point(2).x, point(2).y); // tracé des deux barbes
        fl_line(point(1).x, point(1).y, point(3).x, point(3).y);
      }
    }
     
    //----------------------------------------------------------------------------
     
    void Arrow::barbs_ends()
    {
     
       // Beta est l'angle du corps de la flèche avec l'axe des x
       // point(0) et point(1) représentent dans Shape la queue (0) et l'extrémité (1) de la flèche
     
       double tg_Beta = double(point(1).y-point(0).y)/(point(1).x-point(0).x);
       double Beta = atan(tg_Beta);
     
       double Alpha1 = Alpha - Beta;
       double Alpha2 = Alpha - ((3.14/2)- Beta);
     
       double M1_x, M1_y, M2_x, M2_y; // coordonnées des extrémités M1 et M2 des deux barbes
     
       if (point(1).x > point(0).x) {
         M1_x = -d*cos(Alpha1)+point(1).x;
         M1_y = d*sin(Alpha1)+point(1).y;
         M2_x = d*sin(Alpha2)+point(1).x;
         M2_y = -d*cos(Alpha2)+point(1).y;
       }
       else if (point(1).x < point(0).x) {
         M1_x = d*cos(Alpha1)+point(1).x;
         M1_y = -d*sin(Alpha1)+point(1).y;
         M2_x = -d*sin(Alpha2)+point(1).x;
         M2_y = d*cos(Alpha2)+point(1).y;2;
       }
       else if (point(1).y > point(0).y) {
         M1_x = -d*sin(Alpha)+point(1).x;
         M1_y = -d*cos(Alpha)+point(1).y;
         M2_x = d*sin(Alpha)+point(1).x;
         M2_y = -d*cos(Alpha)+point(1).y;
       } else {
         M1_x = -d*sin(Alpha)+point(1).x;
         M1_y = d*cos(Alpha)+point(1).y;
         M2_x = d*sin(Alpha)+point(1).x;
         M2_y = d*cos(Alpha)+point(1).y;
       }
       Point M1, M2; // les extrémités des barbes
       M1.x = M1_x; M1.y = M1_y; 
       M2.x = M2_x; M2.y = M2_y;
     
       add(M1); // devient point(2)
       add(M2); // devient point(3)
     
    }
     
    //----------------------------------------------------------------------------
     
    int main()
    {
      Simple_window win(Point(10,10), 600, 650, "Arrow");
     
      // flèche avec les barbes "standards"
      Arrow Fleche1(Point(200,150), Point(290,600)); 
     
      // flèche avec des barbes "personnalisées"
      Arrow Fleche2(Point(70,30), Point(270,150), 150, 0.15); 
     
      win.attach(Fleche1);
      win.attach(Fleche2);
      win.wait_for_button();
    }

  16. #16
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Je ne connais (pour l'instant...) rien au calcul matriciel, hélas... Dans ta formule comment obtient-on 'norme BA' ??

    Dans la version précédente de la classe demandée et de son implémentation, la fonction barbs_ends() mettait à jour la 'base de données des points remarquables (=point)' de la classe mère Shape, après avoir calculé les coordonnées de ces points. J'ai pensé qu'il serait sans doute plus satisfaisant (dans la logique : 'une fonction ne fait qu'une chose'+'les constructeurs construisent') de ne donner à cette fonction que la tâche de calcul et d'effectuer la mise à jour de point dans les constructeurs (fût-ce au prix d'une petie duplication de code dans ces constructeurs). Cela donne alors ceci :

    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
    //----------------------------------------------------------------------------
     
    class Arrow : public Shape {
      public:
        Arrow(Point from, Point to); // from = queue de la flèche, to = pointe de la flèche
        Arrow(Point from, Point to, int barb_length, double barb_angle); // barb__length = longueur de la barbe
    						      // barb_angle = angle de la barbe avec le corps de la flèche
     
        void draw_lines() const; // dessine la flèche sur l'écran
     
        int barb_length() const { return d; }
        void set_barb_length(int dd)  { d = dd; }
     
        double barb_angle() { return Alpha;}
        void set_barb_angle(double a) { Alpha = a;}
     
      private:
          int d; // longueur de chacune des barbes de la flèche
          double Alpha; // angle aigu de chaque barbe avec le corps de la flèche, exprimé en radians
          vector<int> barbs_ends(); // renvoie un vecteur contenant les coordonnées des extrémités des barbes 
     
    };
     
    //----------------------------------------------------------------------------
     
    Arrow::Arrow(Point from, Point to) : d(20), Alpha(0.35)
    {
      if (from.x == to.x && from.y == to.y )
        error("Flèche nulle");
     
      add(from); // point(0)
      add(to); // point(1)
     
      vector<int> ends;
      ends = barbs_ends(); // barbs_ends() renvoie un vecteur contenant les coordonnées des extrémités des barbes
      Point M1; M1.x = ends[0]; M1.y = ends[1];
      Point M2; M2.x = ends[2]; M2.y = ends[3];
     
      add(M1); // point(2)
      add(M2); // point(3)
    }
     
    //----------------------------------------------------------------------------
     
    Arrow::Arrow(Point from, Point to, int barb_length, double barb_angle):  d(barb_length), Alpha(barb_angle)
    {
      if (from.x == to.x && from.y == to.y )
        error("Flèche nulle");
      if ( d <= 0 || Alpha <= 0 ) 
        error("Flèche imberbe");
     
      add(from);
      add(to);
     
      vector<int> ends;
      ends = barbs_ends(); // barbs_ends() renvoie un vecteur contenant les coordonnée	s des extrémités des barbes
      Point M1; M1.x = ends[0]; M1.y = ends[1];
      Point M2; M2.x = ends[2]; M2.y = ends[3];
     
      add(M1); // point(2)
      add(M2); 	// point(3)
    }
     
    //----------------------------------------------------------------------------
     
    void Arrow::draw_lines() const
    {
      // point(0) = queue de la flèche, point(1) = tête de la flèche
      if(color().visibility()) {
        fl_line(point(0).x,point(0).y, point(1).x, point(1).y); // tracé du corps de la flèche
     
        fl_line(point(1).x, point(1).y, point(2).x, point(2).y); // tracé des deux barbes
        fl_line(point(1).x, point(1).y, point(3).x, point(3).y);
      }
    }
     
    //----------------------------------------------------------------------------
     
    vector<int> Arrow::barbs_ends()
    {
     
     
       // Beta est l'angle du corps de la flèche avec l'axe des x
       // point(0) et point(1) représentent dans Shape la queue (0) et l'extrémité (1) de la flèche
     
       double tg_Beta = double(point(1).y-point(0).y)/(point(1).x-point(0).x);
       double Beta = atan(tg_Beta);
     
       double Alpha1 = Alpha - Beta;
       double Alpha2 = Alpha - ((3.14/2)- Beta);
     
       double M1_x, M1_y, M2_x, M2_y; // coordonnées des extrémités M1 et M2 des deux barbes
     
       if (point(1).x > point(0).x) {
         M1_x = -d*cos(Alpha1)+point(1).x;
         M1_y = d*sin(Alpha1)+point(1).y;
         M2_x = d*sin(Alpha2)+point(1).x;
         M2_y = -d*cos(Alpha2)+point(1).y;
       }
       else if (point(1).x < point(0).x) {
         M1_x = d*cos(Alpha1)+point(1).x;
         M1_y = -d*sin(Alpha1)+point(1).y;
         M2_x = -d*sin(Alpha2)+point(1).x;
         M2_y = d*cos(Alpha2)+point(1).y;
       }
       else if (point(1).y > point(0).y) {
         M1_x = -d*sin(Alpha)+point(1).x;
         M1_y = -d*cos(Alpha)+point(1).y;
         M2_x = d*sin(Alpha)+point(1).x;
         M2_y = -d*cos(Alpha)+point(1).y;
       } else {
         M1_x = -d*sin(Alpha)+point(1).x;
         M1_y = d*cos(Alpha)+point(1).y;
         M2_x = d*sin(Alpha)+point(1).x;
         M2_y = d*cos(Alpha)+point(1).y;
       }
     
       vector<int> ends;  // pour les coordonnées des extrémités M1 et M2 des deux barbes
          ends.push_back(int(M1_x));
          ends.push_back(int(M1_y));
          ends.push_back(int(M2_x));
          ends.push_back(int(M2_y));
     
        return ends;
    }
     
    //--------------------------p--------------------------------------------------
     
    int main()
    {
      Simple_window win(Point(10,10), 600, 650, "Arrow");
     
      // flèche avec les barbes "standards"
      Arrow Fleche1(Point(200,150), Point(290,400)); 
     
      // flèche avec des barbes "personnalisées"
      Arrow Fleche2(Point(70,30), Point(270,150), 150, 0.15); 
     
      win.attach(Fleche1);
      win.attach(Fleche2);
      win.wait_for_button();
    }

  17. #17
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 43
    Points : 34
    Points
    34
    Par défaut
    Citation Envoyé par ptyxs Voir le message
    Je ne connais (pour l'instant...) rien au calcul matriciel, hélas... Dans ta formule comment obtient-on 'norme BA' ??
    La norme du vecteur BA est en fait la longueur su segment [BA]:

    ->
    norme(BA) (souvent notée ||BA||)=racine((Xa-Xb)²+(Ya-Yb)²)

    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
     
    void Arrow::barbs_ends()
    {
     
       double Norme = sqrt((point(0).x-point(1).x)*(point(0).x-point(1).x)+(point(0).y-point(1).y)*(point(0).y-point(1).y));
     
     
       double M1_x, M1_y, M2_x, M2_y; // coordonnées des extrémités M1 et M2 des deux barbes
     
        double Ix = (point(0).x-point(1).x)/Norme;
        double Iy = (point(0).y-point(1).y)/Norme;
        double Jx = Ix;
        double Jy = -1*Iy;
        double Dx = d*cos(Alpha);
        double Dy = d*sin(Alpha);
     
        M1_x = point(1).x + Dx*Ix - Dy*Jx
        M1_y = point(1).y + Dx*Iy - Dy*Jy
        M2_x = point(1).x + Dx*Ix + Dy*Jx
        M2_y = point(1).y + Dx*Iy + Dy*Jy
     
       Point M1, M2; // les extrémités des barbes
       M1.x = M1_x; M1.y = M1_y; 
       M2.x = M2_x; M2.y = M2_y;
     
       add(M1); // devient point(2)
       add(M2); // devient point(3)
     
    }
    Essaye comme ça ! normalement cela doit marcher aussi (pour la racine carée je suppose que c'est sqrt() ). En fait dans ton cas le calcul matriciel se résume à la multiplication d'une matrice (2 2) et d'un vecteur (2 1), c'est la partie de type "Dx*Ix-Dy*Iy" du calcul .

    Pour ce qui est de la mise à jour de la base de données dans la fonction barbs_ends() ou ne reserver cette fonction que pour le calcul je n'ai pas assez d'expérience en programmation pour te conseiller. Peut etre que la seconde méthode que tu invoque est plus logique mais a-t-elle vraiment un interet ? est ce que le fait de mettre à jour la base dans la fonction Barbs_ends() pose un problème ?

    Cordialement.
    Darki03.

  18. #18
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Il semble que le nouvel algo matriciel (à la différence du précédent) ne fonctionne pas bien pour les flèches horizontales et verticales (aucune barbe n'est alors tracée) :

    flèche verticale pointée vers le haut :
    Arrow Fleche1(Point(200,450), Point(200,400)); BAD

    flèche verticale pointée vers le bas :
    Arrow Fleche1(Point(200,400), Point(200,450)); BAD

    flèche horizontale pointant vers la droite :
    Arrow Fleche1(Point(200,400), Point(250,400)); BAD

    flèche horizontale pointant vers la gauche :
    Arrow Fleche1(Point(250,400), Point(200,400)); BAD

    flèche vers le Nord Ouest :
    Arrow Fleche1(Point(200,450), Point(100,400)); OK

    flèche vers le Sud OUest :
    Arrow Fleche1(Point(200,400), Point(100,450)); OK

    flèche vers le Sud Est :
    Arrow Fleche1(Point(200,400), Point(250,450)); OK

    flèche vers le Nord Est :
    Arrow Fleche1(Point(200,450), Point(250,400)); OK
    Je remets pour plus de clarté la version de la fonction barbs_ends() utilisée :
    (Ix et Jx ou Iy et Jy s'annulent dans ces cas et les bouts de barbe se trouvent sur la flèche elle(même)
    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
     
    vector<int>  Arrow::barbs_ends()
    {
     
      double Norme = sqrt((point(0).x-point(1).x)*(point(0).x-point(1).x)+(point(0).y-point(1).y)*(point(0).y-point(1).y));
     
     
      double M1_x, M1_y, M2_x, M2_y; // coordonnées des extrémités M1 et M2 des deux barbes
     
      double Ix = (point(0).x-point(1).x)/Norme;
      double Iy = (point(0).y-point(1).y)/Norme;
      double Jx = Ix;
      double Jy = -1*Iy;
      double Dx = d*cos(Alpha);
      double Dy = d*sin(Alpha);
     
      M1_x = point(1).x + Dx*Ix - Dy*Jx;
      M1_y = point(1).y + Dx*Iy - Dy*Jy;
      M2_x = point(1).x + Dx*Ix + Dy*Jx;
      M2_y = point(1).y + Dx*Iy + Dy*Jy;
     
      vector<int> ends;  // pour les coordonnées des extrémités M1 et M2 des deux barbes
            ends.push_back(int(M1_x));
            ends.push_back(int(M1_y));
            ends.push_back(int(M2_x));
            ends.push_back(int(M2_y));
     
      return ends;
    }

  19. #19
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 43
    Points : 34
    Points
    34
    Par défaut
    -_-' j'ai fait une bourde en réecrivant la fonction barbs_ends() (dans le second fichier excel et le calculs de Sopsag c'etait bon ^^):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      double Ix = (point(0).x-point(1).x)/Norme;
      double Iy = (point(0).y-point(1).y)/Norme;
      double Jx = Iy;
      double Jy = -1*Ix;
    ça devrait mieux marcher comme ça (avec la bourde le second repère basé sur la fleche n'etait pas orthonormé direct )

    Cordialement.
    Darki03.

  20. #20
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Voilà, eh bien encore merci, ça colle cette fois.
    Je donne ci-dessous l'ensemble. J'ai encore modifié barbs_ends() de façon que la fonction soit indépendante du programme appelant, afin qu'il soit possible de l'utiliser dans un autre contexte.

    Pour ceux qui souhaiteraient avoir la fonction mère Shape de Stroustup, on la trouve ici :
    http://www.stroustrup.com/Programming/Graphics/
    (fichiers Graph.h et Graph.cpp)
    Pour que tout fonctionne il faut charger la bibliothèque graphique FLTK :
    http://www.fltk.

    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
     
    const double Barb_angle 0.35 // angle par défaut d'une barbe avec sa flèche
    const int Barb_length 20 // longueur par défaut d'une barbe
     
    //----------------------------------------------------------------------------
     
    class Arrow : public Shape {
      public:
        Arrow(Point from, Point to); // from = queue de la flèche, to = pointe de la flèche
        Arrow(Point from, Point to, int barb_length, double barb_angle); // barb__length = longueur de la barbe
    						      // barb_angle = angle de la barbe avec le corps de la flèche
     
        void draw_lines() const; // dessine la flèche sur l'écran
     
        int barb_length() const { return d; }
        void set_barb_length(int dd)  { d = dd; }
     
        double barb_angle() { return Alpha;}
        void set_barb_angle(double a) { Alpha = a;}
     
      private:
          int d; // longueur de chacune des barbes de la flèche
          double Alpha; // angle aigu de chaque barbe avec le corps de la flèche, exprimé en radians
          vector<int> barbs_ends(const Point& A, const Point& B, const int& d, const double& Alpha) const; // renvoie un vecteur contenant les coordonnées des extrémités des barbes 
     
    };
     
    //----------------------------------------------------------------------------
     
    Arrow::Arrow(Point from, Point to) 
    : d(Barb_length), Alpha(Barb_angle)
    {
      if (from.x == to.x && from.y == to.y )
        error("Flèche nulle");
     
      add(from); // point(0)
      add(to); // point(1)
     
      vector<int> ends;
      ends = barbs_ends(point(0),point(1),d,Alpha); // barbs_ends() renvoie un vecteur contenant les coordonnées des extrémités des barbes
      Point M1; M1.x = ends[0]; M1.y = ends[1];
      Point M2; M2.x = ends[2]; M2.y = ends[3];
     
      add(M1); // point(2)
      add(M2); // point(3)
    }
     
    //----------------------------------------------------------------------------
     
    Arrow::Arrow(Point from, Point to, int barb_length, double barb_angle)
    :  d(barb_length), Alpha(barb_angle)
    {
      if (from.x == to.x && from.y == to.y )
        error("Flèche nulle");
      if ( d <= 0 || Alpha <= 0 ) 
        error("Flèche imberbe");
     
      add(from);
      add(to);
     
      vector<int> ends;
      ends = barbs_ends(point(0),point(1),d,Alpha); // barbs_ends() renvoie un vecteur contenant les coordonnée	s des extrémités des barbes
      Point M1; M1.x = ends[0]; M1.y = ends[1];
      Point M2; M2.x = ends[2]; M2.y = ends[3];
     
      add(M1); // point(2)
      add(M2); // point(3)
    }
     
    //----------------------------------------------------------------------------
     
    void Arrow::draw_lines() const
    {
      // point(0) = queue de la flèche, point(1) = tête de la flèche
      if(color().visibility()) {
        fl_line(point(0).x,point(0).y, point(1).x, point(1).y); // tracé du corps de la flèche
     
        fl_line(point(1).x, point(1).y, point(2).x, point(2).y); // tracé des deux barbes
        fl_line(point(1).x, point(1).y, point(3).x, point(3).y);
      }
    }
     
    //----------------------------------------------------------------------------
     
    vector<int> Arrow::barbs_ends(const Point& A, const Point& B, const int& d, const double& Alpha) const
    {
      // A = queue de la flèche, B = pointe de la flèche
      // d = longueur de chaque barbe
      // Alpha = angle de la barbe avec le corps de la flèche, en radians
     
      // la fonction renvoie un vecteur contenant les coordonnées x,y des points M1 (v[0],v[1])
      // et  M2 ((v[2],v[3]) tels que :
      // BM1 = barbe gauche (en regardant la pointe depuis la queue)
      // BM2 = barbe droite (en regardant la pointe depuis la queue)
     
      // Norme = distance AB
      double Norme = sqrt( pow(A.x-B.x,2) + pow(A.y-B.y,2) );
     
     
      double M1_x, M1_y, M2_x, M2_y; // coordonnées des extrémités M1 et M2 des deux barbes
     
      double Ix = (A.x-B.x)/Norme;
      double Iy = (A.y-B.y)/Norme;
      double Jx = Iy;
      double Jy = -1*Ix;
      double Dx = d*cos(Alpha);
      double Dy = d*sin(Alpha);
     
      M1_x = B.x + Dx*Ix - Dy*Jx;
      M1_y = B.y + Dx*Iy - Dy*Jy;
      M2_x = B.x + Dx*Ix + Dy*Jx;
      M2_y = B.y + Dx*Iy + Dy*Jy;
     
      vector<int> ends;  // pour les coordonnées des extrémités M1 et M2 des deux barbes
          ends.push_back(int(M1_x));
          ends.push_back(int(M1_y));
          ends.push_back(int(M2_x));
          ends.push_back(int(M2_y));
     
      return ends;
    }
     
    //----------------------------------------------------------------------------
     
    int main()
    {
      Simple_window win(Point(10,10), 600, 650, "Arrow");
     
      // flèche avec les barbes "standards"
      Arrow Fleche1(Point(250,400), Point(200,400));
     
      // flèche avec des barbes "personnalisées"
      Arrow Fleche2(Point(70,30), Point(270,150), 150, 0.15); 
     
      win.attach(Fleche1);
      win.attach(Fleche2);
      win.wait_for_button();
    }

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Comment dessiner une fléche comme ceci ?
    Par jlassiramzy dans le forum AWT/Swing
    Réponses: 6
    Dernier message: 24/04/2007, 02h57
  2. Comment dessiner une flèche ?
    Par Amine_sas dans le forum 2D
    Réponses: 4
    Dernier message: 20/12/2006, 21h58
  3. Comment dessiner une petite interface de radar?
    Par jlassiramzy dans le forum AWT/Swing
    Réponses: 8
    Dernier message: 26/06/2006, 23h06
  4. Réponses: 3
    Dernier message: 29/06/2005, 14h29
  5. Comment dessiner une ligne dans un Chart ?
    Par libititi dans le forum Composants VCL
    Réponses: 3
    Dernier message: 16/06/2005, 14h56

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