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 :

[TCanvas] peindre une forme géométrique


Sujet :

C++Builder

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 71
    Par défaut [TCanvas] peindre une forme géométrique
    Bonjour !

    Voilà j'aimerai peindre ( par une couleur ou un bitmap ) une forme géométrique délimitée par deux autres.

    Il faut s'imaginer un cercle avec à l'intérieur un segment de longueur est variable et ce segment peut se déplacer dans le cercle mais il est toujours contenu dans le cercle ( pour les amateur de simulateurs d'avion c'est un horizon artificiel ). Ce Segment partage donc le cercle en deux zones que j'aimerai peindre dans une couleur différente.

    Le cercle reste fixe dans mon Canvas ( j'utilise PaintBox ).

    Voilà ne sachant pas comment faire, je sollicite votre aide !

  2. #2
    Membre Expert

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    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
    int Horizon = 0;
    double pi = 3.14159265358979;
     
    //--
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    PaintBox1->Width = 200;
    PaintBox1->Height = 200;
    }
    //--
    void __fastcall TForm1::PaintBox1Paint(TObject *Sender)
    {
    TCanvas *C = PaintBox1->Canvas;
    int w = PaintBox1->Width;
    int h = PaintBox1->Height;
    //Effacer
    C->Pen->Color = clSilver;
    C->Pen->Mode = pmCopy;
    C->Pen->Style = psSolid;
    C->Brush->Color = clSilver;
    C->Brush->Style = bsSolid;
    C->Rectangle(0,0,w,h);
    //Le cercle
    C->Pen->Color = clBlack;
    C->Brush->Style = bsClear;
    C->Ellipse(0,0,w,h);
    //Le segment. Rappel : Horizon varie de  0 à 359°
    int r = w / 2;
    double a = Horizon;
    a = a * pi  / 180.0;
    double dx = cos(a) * r;
    double dy = sin(a) * r;
    C->MoveTo(r + dx, r - dy);
    a = a + pi;
    dx = cos(a) * r;
    dy = sin(a) * r;
    C->LineTo(r + dx, r - dy);
    //coloriser le ciel
    a = Horizon + 90;
    a = a * pi  / 180.0;
    dx = cos(a) * r / 2.0;
    dy = sin(a) * r / 2.0;
    C->Brush->Color = clAqua;
    C->FloodFill(r + dx, r - dy, clSilver, fsSurface);
    //Coloriser la terre
    a = Horizon + 270.0;
    a = a * pi  / 180.0;
    dx = cos(a) * r / 2.0;
    dy = sin(a) * r / 2.0;
    C->Brush->Color = clMaroon;
    C->FloodFill(r + dx, r - dy, clSilver, fsSurface);
     
    /*
    Normalement il faudrait tenir compte de deux paramètres :
    - L'inclinaison des ailes (c'est ce que j'ai montré)
    - L'inclinaison du nez
    La petite imperfection peut se corriger en arrondissant à partir de +0.5 ou -0.5
    ce que je n'ai pas voulu faire ici.
    Je pense que ça devrait aller non ?
     
    */
    }
    A plus !

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 71
    Par défaut
    .... heu ... Merci beaucoup ! J' en attendais pas tant ! Mais le problème pour moi, c'est que je code sous Kylix 3 C++ et je n'ai pas la méthode FloodFill dans ma classe Canvas ( pourquoi d'ailleur ? ). Avez vous un équivalent ?

  4. #4
    Membre Expert

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut

    Désolé de t'en avoir donné autant ! (d'ailleurs c'est très peu !)
    Peut-être sur le forum Kylix ? Ici c'est le forum BCB.
    FloodFill existe également dans les API WINDOWS.

    A plus !

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 71
    Par défaut
    Dans cet exemple, tu ne tiens compte que de l'inclinaison des ailes ( roulis ) mais comment fais tu pour l'inclinaison du nez ( tangage ). Je sais comment ce comporte l'horizon artificiel mais je n'arrive pas le simuler, cad trouver x et y en fonction du roulis et du tangage.

  6. #6
    Membre Expert

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Voici le processus complèt. J'avais oublié le fait que lors d'un looping
    la terre ne réapparait pas d'où elle a disparu mais à l'opposé...
    enfin je crois... parce que je ne sais plus !!!!!!!!
    En tout cas ça justifie la réécriture de la réponse !

    J'ai simulé l'action du manche avec les touches flêches :
    VK_UP pour pousser le manche
    VK_DOWN pour tirer le manche
    VK_RIGHT pour infléchir à droite
    VK_LEFT pour infléchir à gauche

    Les petits carrés jaunes qui apparaissent sont là pour montrer le point
    à partir du quel, j'applique le FloodFill. Tu pourras donc supprimer le code
    qui permet de les dessiner.

    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
    Graphics::TBitmap *Assiette = new Graphics::TBitmap;
    int Ailes = 0;
    int Nez = 0;
    double pi = 3.14159265358979;
     
    //--
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    Assiette->Width = 201;
    Assiette->Height = 201;
    }
    //--
    int Arrondir(double D)
    {
    int a = D;
    double r = (D - a) * 2;
    return(a + r);
    }
    //--
     
    double DegToRadians(int A)
    {
    return((double)A * pi / 180);
    }
    //-
     
    void Conformer(int *A)
    {
    if(*A < 0)
        {
        *A = 360 + *A;
        }
    else
        {
        if(*A >= 360)
            {
            *A = *A % 360;
            }
        }
    }
    //-
    void __fastcall TForm1::DrawAssiette()
    {
    int x;
    int y;
    double h;
    double a;
    double r;
    double sina;
    double cosa;
    double sinb;
    double cosb;
    double x_gauche;
    double x_droite;
    TColor Ciel = clAqua;
    TColor Terre = clMaroon;
     
    if(Assiette != NULL)//Assiette est un bitmap 201 * 201//impair à cause de....
        {
        TCanvas *C = Assiette->Canvas;
        //Effacer
        C->Pen->Color = clSilver;
        C->Pen->Mode = pmCopy;
        C->Pen->Style = psSolid;
        C->Brush->Color = clSilver;
        C->Brush->Style = bsSolid;
        C->Rectangle(0,0,201,201);
        //Le cadre
        C->Pen->Color = clBlack;
        C->Brush->Style = bsClear;
        //je dédouble le cadre pour éviter les problèmes lors du remplissage
        C->Ellipse(0,0,201,201);
        C->Ellipse(2,2,199,199);
        //On calcule l'horizon par rapport à l'angle du nez.
        r = 100.0; //rayon
        Conformer(&Nez);
        if((Nez >= 90)&&(Nez < 270))
            {
            //ici on est "tête en bas" lors du looping
            a = DegToRadians(360.0 - Nez);
            Ciel = clMaroon;
            Terre = clAqua;
            }
        else
            {
            a = DegToRadians(Nez);
            }
        h = Arrondir(sin(a) * r);
        x = Arrondir(cos(a) * r);
        C->Pen->Color = clBlack;
        x_gauche = - x;
        x_droite = + x;
     
        //Calcul sinus et cosinus de l'angle d'inclinaison pour les Ailes
        Conformer(&Ailes);
        a = DegToRadians(Ailes);  //angle en radians
        sinb = sin(a);
        cosb = cos(a);
     
        //rotation des points x_droite et x_gauche
        sina =  h / r; //les points ont le même sinus
        //Pour le premier point :
        cosa = x_gauche / r;
        y = Arrondir(((sina * cosb) + (sinb * cosa)) * r);
        x = Arrondir(((cosa * cosb) - (sina * sinb)) * r);
        C->MoveTo(r + x, r + y);
     
        //pour le deuxième point
        cosa = x_droite / r;
        //idem
        y = Arrondir(((sina * cosb) + (sinb * cosa)) * r);
        x = Arrondir(((cosa * cosb) - (sina * sinb)) * r);
        C->LineTo(r + x, r + y);
     
        //Remplissage : ciel ou terre selon la couleur Ciel
        //r-1 à cause des angles 45°, 135° etc.
        a = DegToRadians(Ailes + 270);
        x = Arrondir(cos(a) * (r - 1 - h) / 2.0);
        y = Arrondir(sin(a) * (r - 1 - h) / 2.0);
     
        C->Brush->Color = Ciel;
        C->FloodFill(r + x, r + y, clSilver, fsSurface);
                //---------supprimer ces trois lignes
                C->Pen->Color = clBlack;
                C->Brush->Color = clYellow;
                C->Rectangle(   r + (x - 2), r + (y - 2), r + (x + 2), r + (y + 2));
                //---------
        //Remplissage terre ou ciel selon la couleur Terre
        a = DegToRadians(Ailes + 90);
        x = Arrondir(cos(a) * (r - 1 + h) / 2.0);
        y = Arrondir(sin(a) * (r - 1 + h) / 2.0);
        C->Brush->Color = Terre;
        C->FloodFill(r + x, r + y, clSilver, fsSurface);
                //---------à supprimer ces trois lignes
                C->Pen->Color = clBlack;
                C->Brush->Color = clYellow;
                C->Rectangle(   r + (x - 2), r + (y - 2), r + (x + 2), r + (y + 2));
                //---------
        //horizon
        C->Pen->Color = clRed;
        C->MoveTo(1,99); C->LineTo(200,99);
        C->Pen->Color = clBlue;
        C->MoveTo(1,100); C->LineTo(200,100);
        C->Pen->Color = clRed;
        C->MoveTo(1,101); C->LineTo(200,101);
        Canvas->Draw(40,40,Assiette);//copie sur la form
        }
    }
     
    //--
    void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift)
    {
    if(Key == VK_LEFT)
        {
        Ailes-=3; DrawAssiette(); Key = 0;
        }
    if(Key == VK_RIGHT)
        {
        Ailes+=3; DrawAssiette(); Key = 0;
        }
    if(Key == VK_UP)
        {
        Nez -=3; DrawAssiette(); Key = 0;
        }
    if(Key == VK_DOWN)
        {
        Nez +=3; DrawAssiette(); Key = 0;
        }
    }
    //---------------------------------------------------------------------------
     
    void __fastcall TForm1::FormPaint(TObject *Sender)
    {
    DrawAssiette();
    }
    //---------------------------------------------------------------------------
     
    void __fastcall TForm1::FormResize(TObject *Sender)
    {
    DrawAssiette();
    }
    //---------------------------------------------------------------------------
    A plus !

  7. #7
    Membre Expert

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    J'ai modifié la réponse précédente.
    Ici, ça fonctionne !

    A plus !

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 71
    Par défaut
    Je te remercie beaucoup, je n'ai pas encore trouvé de fonction me permettant de remlir mes formes géométriques sous kylix mais ton code fonctionne bien. Je pense que je vais dessinner par dessus une image pour une esthétique plus réussi. Merci encore.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/04/2009, 20h51
  2. Insérer une forme géométrique dans un jpanel
    Par ieaiaio dans le forum Débuter
    Réponses: 6
    Dernier message: 08/04/2009, 16h56
  3. decoupage d'une forme géométrique en carrés de 32*32
    Par AnozerOne dans le forum Mathématiques
    Réponses: 8
    Dernier message: 18/03/2008, 22h22
  4. Réponses: 2
    Dernier message: 04/12/2007, 00h24
  5. glVertex et définition d'une forme géométrique
    Par Mastero dans le forum OpenGL
    Réponses: 1
    Dernier message: 06/12/2004, 12h44

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