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

VB.NET Discussion :

Changer l'échelle d'un dessin avec ScaleTransform


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Juin 2002
    Messages
    198
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 198
    Par défaut Changer l'échelle d'un dessin avec ScaleTransform
    Bonjour,
    Je m’initie au "graphics". J’essaie d'implémenter la méthode "ScaleTransform" hélas sans succès.
    Je souhaite changer l'échelle de mon oGraphics.
    Programme : dessiner le triangle d'un nombre.
    Tboxe1 : valeur demandée.
    Tboxe2 : info valeur est un triangle.
    PicBox : surface pour dessiner.
    Button_click sur une forme:
    Le site de Microsoft ne m'est pas très clair. Merci d'avance de votre aide.
    Clovis.

    Voir ligne 48 pour la transformation
    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
     
    Private Sub BTTriangle_Click(sender As Object, e As EventArgs) Handles BTTriangle.Click
            TextBox2.Text = " "
     
            Dim oVal, i, som As Integer
     
            i = 1
            som = 0
            oVal = TextBox1.Text
     
     
            'drawing
            Dim oCol, oSpace, oCount, oRow As Integer
            Dim oPen As Pen
            oPen = New Pen(Drawing.Color.DarkCyan, 2)
            Dim oGraphics As Graphics = Me.PicBox.CreateGraphics
            oGraphics.Clear(SystemColors.Control)
            Dim oRect As New Rectangle
     
            oSpace = 10
            oRect.X = PicBox.Width / 2
            oRect.Y = oSpace
            oRect.Width = oSpace
            oRect.Height = oSpace
            oCol = oRect.X
            oCount = 0
     
            While som < oVal
                oRow += 1
                som = som + i
                i = 1 + i
                oRect.X = oCol
     
                For j = 1 To i - 1
                    oCount += 1
                    If oCount > oVal Then
                        oPen.Color = Color.Red
                    End If
                    oGraphics.DrawEllipse(oPen, oRect)
                    oRect.X += oSpace * 2
                Next
     
                oRow += 1
                oCol -= oSpace
                oRect.Y += 20
            End While
     
            If oRow > 9 Then
                oGraphics.ScaleTransform(0.5, 0.5) '<----------------- ICI ---------------------
            End If
            If som = oVal Then
                TextBox2.Text = "triangle"
            Else
                TextBox2.Text = "not triangle: " & (oVal - oCount).ToString & " too little"
            End If
     
            'Debug.Print("ici")
        End Sub

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    Le scale transform agit sur tout ce qui est draw après, donc à faire avant de draw
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre Expert Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Par défaut
    En effet, comme te le signale Pol63, ton facteur d'échelle doit être réglé avant de dessiner.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            g.ScaleTransform(0.5, 1) 
            g.DrawEllipse(New Pen(Color.Red), r)
    Bon amusement ...

  4. #4
    Membre confirmé
    Inscrit en
    Juin 2002
    Messages
    198
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 198
    Par défaut
    Donc j'essaie d'utiliser mauvaise méthode pour ma solution.
    Quelle méthode devrais-je employer pour changer l'échelle de mon dessin après sa finition?

    +tard je vais essayer de changer l'échelle avec le mouse_wheel event que je n'ai pas encore vu dans Visual Studio Community 2015.

    Merci

  5. #5
    Membre Expert Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Par défaut
    Bonjour,

    Si tu veux "re"dessiner avec des dimension différentes, tu peux toujours effacer le dessin et le recommencer.
    C'est pas très élégant, mais ça fait ce que tu demandes ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        ''************ Dessin dans un Panel
        Private Sub Panel2_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel2.Paint
            Dim g As Graphics = e.Graphics
            Dim r As New RectangleF(0, 0, 100, 100)
     
            g.DrawEllipse(New Pen(Color.Red), r) ' 1er dessin
     
            g.Clear(Panel2.BackColor) ' effacement
     
            g.ScaleTransform(0.5, 1)  ' nouvelle échelle
     
            g.DrawEllipse(New Pen(Color.Red), r) ' 2ème dessin
     
        End Sub
    Bonne journée,

  6. #6
    Membre Expert
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Par défaut
    Bonjour,

    Citation Envoyé par Phil Rob Voir le message
    Bonjour,
    Si tu veux "re"dessiner avec des dimension différentes, tu peux toujours effacer le dessin et le recommencer.
    C'est pas très élégant, mais ça fait ce que tu demandes ...
    Surtout c'est quoi l'intérêt de dessiner un truc pour l'effacer juste après ? Autant dessiner directement à l'échelle souhaitée. En effet, comme le fait Phil Rob, il faut dessiner dans le paint du Control.
    Ensuite en cas de changement d'échelle, un simple Control.Invalidate() permettra le rafraîchissement du dessin.

  7. #7
    Membre Expert Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Par défaut
    Bonjour ebastien,

    Ta solution est effectivement bien plus élégante que la mienne mais elle peut poser problème ...

    L'exemple que j'ai posté ce matin est une réponse à l'événement Paint. Ta solution ne convient dans ce cas parce que la méthode Invalidate provoque l'événement Paint. Il s'en suit une boucle sans fin ...

    Je suppose que cela nécessite une autre organisation du code ..., si tu as une suggestion ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        ''************ Dessin dans un Panel
        Private Sub Panel2_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel2.Paint
            Dim g As Graphics = e.Graphics
            Dim r As New RectangleF(0, 0, 100, 100)
     
            g.ScaleTransform(0.5, 1)  ' Mise à l'échelle
     
            Panel2.Invalidate()   ' ATTENTION : Provoque l'événement Paint
     
            g.DrawEllipse(New Pen(Color.Red), r) ' 1er dessin
     
        End Sub

  8. #8
    Membre confirmé
    Inscrit en
    Juin 2002
    Messages
    198
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 198
    Par défaut
    Après avoir lu vos commentaires (merci beaucoup pour vos aides!!) je pense que je devrais faire, en premier lieu, le calcul théorique des dimensions de mon dessin, tester les limites après quoi seulement dessiner.

    Dans Microsoft Office on peut utiliser Ctrl+Mouse_Wheel pour changer le zoom. C'est le type de changement d'échelle que je voudrais finalement implémenter à coter du changement d'échelle automatique.

    Merci

  9. #9
    Membre Expert
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Par défaut
    Effectivement, il ne faut pas appeler la méthode Invalidate() dans l'évènement Paint ! Comme tu le soulignes, cela engendre une demande de rafraîchissement du Control et aura pour effet de rappeler l'event Paint (boucle sans fin).


    L'idée sera de définir les paramètres sx et sy de ScaleTransform(..) en variable globale (ou mieux en propriété avec getter et setter) et d'appeler Invalidate() lors de la modification d'une de ces valeurs :

    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
     
        Private sx As Single = 1
        Private sy As Single = 1
     
        Private Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint
            Dim g As Graphics = e.Graphics
            Dim r As New RectangleF(0, 0, 100, 100)
            g.ScaleTransform(sx, sy)  ' Mise à l'échelle
            g.DrawEllipse(New Pen(Color.Red), r) ' 1er dessin
        End Sub
     
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            sx = sx / 1.2
            sy = sy / 1.2
            Panel1.Invalidate()
        End Sub
    Et au passage éviter aussi la création de l'objet Pen dans le Paint car c'est un objet qui implémente l'interface IDisposable. Il doit donc être "disposé". Un New, un Dispose()

  10. #10
    Membre Expert
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Par défaut
    Ok je peux ajouter ceci pour le MouseWheel :

    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
     
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            AddHandler Me.MouseWheel, AddressOf MyMouseWheel
       End Sub
     
     Private Sub MyMouseWheel(sender As Object, e As MouseEventArgs)
            If (e.Delta >= 0) Then
                sx = sx / 1.1
                sy = sy / 1.1
            End If
            If (e.Delta <= 0) Then
                sx = sx * 1.1
                sy = sy * 1.1
            End If
            Panel1.Invalidate()
        End Sub

  11. #11
    Membre Expert Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Par défaut
    Tes réponses sont pertinentes et complètes !
    Bravo ebastien et merci ...
    Je suppose que clovis y trouvera son bonheur ...

  12. #12
    Membre confirmé
    Inscrit en
    Juin 2002
    Messages
    198
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 198
    Par défaut
    Un grand merci pour à tous - surtout à Ebastien - pour vos aides .... j'en ai les frissons.

Discussions similaires

  1. Changer l'échelle d'une courbe avec une proc lifetest
    Par nicoczyck dans le forum SAS STAT
    Réponses: 1
    Dernier message: 04/06/2009, 10h14
  2. Dessiner avec wxWidgets
    Par SuperPat dans le forum wxWidgets
    Réponses: 5
    Dernier message: 24/02/2009, 01h06
  3. Réponses: 1
    Dernier message: 26/02/2005, 13h55
  4. Changer les couleurs de la palette avec du RGB
    Par le mage tophinus dans le forum x86 16-bits
    Réponses: 11
    Dernier message: 13/01/2003, 09h55

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