Création de rectangles rapidement dans vb.net

Résolu
Spoonyx Messages postés 5 Date d'inscription vendredi 11 février 2011 Statut Membre Dernière intervention 2 janvier 2012 - 2 janv. 2012 à 12:17
Spoonyx Messages postés 5 Date d'inscription vendredi 11 février 2011 Statut Membre Dernière intervention 2 janvier 2012 - 2 janv. 2012 à 15:47
Bonjour,

Je cherche à reproduire graphiquement un tableau sous forme de carrés de différentes couleurs assemblés dans ma form.
J'ai écrit ce code:

'Affichage du carré final selon la matrice calculée
        Dim ObjDessin As System.Drawing.Graphics = Me.CreateGraphics() 'Création de l'object graphique
        Dim t As Double = (Me.Height - 80) / i 'Calcul de la taille d'un côté du la figure en cases
        For x As Integer = 0 To i - 1
            For z As Integer = 0 To i - 1
                'Définition d'un objet de taille de t x t à l'emplacement (z * t) + 20, (x * t) + 20
                Dim ObjGraph As New System.Drawing.Rectangle((z * t) + 20, (x * t) + 20, t, t) 
                Select Case tableau(x, z)
                    Case "FeuG"
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Silver, ObjGraph) 'Affichage du rectangle
                        ObjDessin.FillRectangle(Brushes.Silver, ObjGraph) 'Remplissage du rectangle
                    Case "FeuR"
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Red, ObjGraph)
                        ObjDessin.FillRectangle(Brushes.Red, ObjGraph)
                    Case "Limite"
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Orange, ObjGraph)
                        ObjDessin.FillRectangle(Brushes.Orange, ObjGraph)
                    Case "Arbre"
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Green, ObjGraph)
                        ObjDessin.FillRectangle(Brushes.Green, ObjGraph)
                    Case "Sol"
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Yellow, ObjGraph)
                        ObjDessin.FillRectangle(Brushes.Yellow, ObjGraph)
                    Case "CoupeFeu"
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Indigo, ObjGraph)
                        ObjDessin.FillRectangle(Brushes.Indigo, ObjGraph)
                    Case "Eau"
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Blue, ObjGraph)
                        ObjDessin.FillRectangle(Brushes.Blue, ObjGraph)
                End Select
            Next
        Next


Ce code marche très bien, cependant il est très long à exécuter (1 minute pour 250000 cases sur ma machine).
Ma question est donc: Y a t-il un moyen de faire la même chose mais plus rapidement ?

Cordialement, Spoonyx.

9 réponses

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
2 janv. 2012 à 12:42
En gros :

       Dim BackBuffer As Image = New Bitmap(Me.ClientSize.Height, Me.ClientSize.Width)
        Using g As Graphics = Graphics.FromImage(BackBuffer)
            Dim i = 250
            Dim tableau(i, i) As Integer
            Dim t As Double = Me.ClientSize.Height / i
            Dim R As New Rectangle(0, 0, t, t)
            For x As Integer = 1 To i
                For z As Integer = 0 To i
                    Select Case tableau(x, z)
                        Case 1 '"FeuG"
                            g.DrawRectangle(Pens.Silver, R) 'Affichage du rectangle
                            g.FillRectangle(Brushes.Silver, R) 'Remplissage du rectangle
                        Case 2 '"FeuR"
                            g.DrawRectangle(Pens.Red, R)
                            g.FillRectangle(Brushes.Red, R)
                        Case 3 '"Limite"
                            g.DrawRectangle(Pens.Orange, R)
                            g.FillRectangle(Brushes.Orange, R)
                        Case 4 ' "Arbre"
                            g.DrawRectangle(Pens.Green, R)
                            g.FillRectangle(Brushes.Green, R)
                        Case 5 '"Sol"
                            g.DrawRectangle(Pens.Yellow, R)
                            g.FillRectangle(Brushes.Yellow, R)
                        Case 6 '"CoupeFeu"
                            g.DrawRectangle(Pens.Indigo, R)
                            g.FillRectangle(Brushes.Indigo, R)
                        Case 7 '"Eau"
                            g.DrawRectangle(Pens.Blue, R)
                            g.FillRectangle(Brushes.Blue, R)
                        Case Else
                            g.DrawRectangle(Pens.Blue, R)
                            g.FillRectangle(Brushes.Blue, R)
                    End Select
                    R.Offset(t, 0)
                Next
                R.Offset(-R.Left, t)
            Next
        End Using
        Me.CreateGraphics.DrawImage(BackBuffer, 0, 0)


Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
3
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
2 janv. 2012 à 12:27
ne dessines pas sur ta Form...
ca force un rafraichissment a chaque etape intermédiaire


a défault de jouer avec une surface intermédiaire,
ajoutes au moins un suspendLayout / ResumeLayout pour encadrer ton code.

ensuites, pas optimal ton tableau de String, c'est plutot lourd a comparer, deux strings.


Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
2 janv. 2012 à 12:29
ah, etc instancier ton rectange a chaque itération, c'est de la folie :

Dim ObjGraph As New System.Drawing.Rectangle((z * t) + 20, (x * t) + 20, t, t)


crée un rectangle, dont tu décales Left et Top

Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
0
Spoonyx Messages postés 5 Date d'inscription vendredi 11 février 2011 Statut Membre Dernière intervention 2 janvier 2012
2 janv. 2012 à 13:03
Tout d'abord merci pour ta réponse très rapide Renfield.
J'ai essayer de suivre tes conseils, voila mon nouveau code:

'Affichage du carré final selon la matrice calculée
        Me.SuspendLayout()
        Dim t As Double = (Me.Height - 80) / i 'Calcul de la taille d'un côté du la figure en cases
        Dim ObjDessin As System.Drawing.Graphics = Me.CreateGraphics() 'Création de l'object graphique
        Dim ObjGraph As New System.Drawing.Rectangle(20, 20, t, t)
        'Dim ObjGraph As New System.Drawing.Rectangle((z * t) + 20, (x * t) + 20, t, t)
        For x As Integer = 0 To i - 1
            For z As Integer = 0 To i - 1
                ObjGraph.Top = (z * t) + 20
                ObjGraph.Left = (x * t) + 20
                Select Case tableau(x, z)
                    Case 0
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Silver, ObjGraph) 'Affichage du rectangle
                        ObjDessin.FillRectangle(Brushes.Silver, ObjGraph) 'Remplissage du rectangle
                    Case 1
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Red, ObjGraph)
                        ObjDessin.FillRectangle(Brushes.Red, ObjGraph)
                    Case 2
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Orange, ObjGraph)
                        ObjDessin.FillRectangle(Brushes.Orange, ObjGraph)
                    Case 3
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Green, ObjGraph)
                        ObjDessin.FillRectangle(Brushes.Green, ObjGraph)
                    Case 4
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Yellow, ObjGraph)
                        ObjDessin.FillRectangle(Brushes.Yellow, ObjGraph)
                    Case 5
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Indigo, ObjGraph)
                        ObjDessin.FillRectangle(Brushes.Indigo, ObjGraph)
                    Case 6
                        ObjDessin.DrawRectangle(System.Drawing.Pens.Blue, ObjGraph)
                        ObjDessin.FillRectangle(Brushes.Blue, ObjGraph)
                End Select
            Next
        Next
        Me.ResumeLayout()


Visual studio me dit que ObjGraph.Top et ObjGraph.Left sont en ReadOnly...
Quelqu'un saurait-il comment faire?

Merci d'avance !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
2 janv. 2012 à 13:07
Toi, t'as pas lu mon code...


Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
0
Spoonyx Messages postés 5 Date d'inscription vendredi 11 février 2011 Statut Membre Dernière intervention 2 janvier 2012
2 janv. 2012 à 13:18
J'écrivais une réponse quand tu a postés ton code. Un grand merci car il est presque 3 fois plus rapides que le mien (20 secondes pour 250000 cases). Cependant je ne parvient plus à centré le carré final (en laissant une marge de 20 pixels sur les côtés). Si je réussis je posterais le code.

Encore merci!
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
2 janv. 2012 à 14:50
décalage de 20 pixels ?

changer :

Dim R As New Rectangle(0, 0, t, t)
en
Dim R As New Rectangle(20, 20, t, t)

et

R.Offset(-R.Left, t)
en
R.Offset(20-R.Left, t)

Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
0
Spoonyx Messages postés 5 Date d'inscription vendredi 11 février 2011 Statut Membre Dernière intervention 2 janvier 2012
2 janv. 2012 à 14:53
J'ai réussi à faire une marge de 20 pixels, mais je ne comprends pas pourquoi le carré final n'est pas centré, selon le nombre de cases il est disposé différemment et sa taille diffère...
Je remet ton code Renfield que j'ai légèrement modifié:
Dim BackBuffer As Image = New Bitmap(Me.ClientSize.Height, Me.ClientSize.Width)
        Using g As Graphics = Graphics.FromImage(BackBuffer)
            Dim i = 250
            Dim tableau(i, i) As Integer
            Dim t as double = (Me.ClientSize.height - 80) / i 'Calcul de la taille d'un côté de la figure en cases
            Dim R As New Rectangle(0, 20, t, t)
            For x As Integer = 0 To i - 1
                For z As Integer = 0 To i - 1
                    If z = 0 Then R.Offset(t + 20, 0) Else R.Offset(t, 0)
                    Select Case tableau(x, z)
                        Case 0 '"FeuG"
                            g.DrawRectangle(Pens.Silver, R) 'Affichage du rectangle
                            g.FillRectangle(Brushes.Silver, R) 'Remplissage du rectangle
                        Case 1 '"FeuR"
                            g.DrawRectangle(Pens.Red, R)
                            g.FillRectangle(Brushes.Red, R)
                        Case 2 '"Limite"
                            g.DrawRectangle(Pens.Orange, R)
                            g.FillRectangle(Brushes.Orange, R)
                        Case 3 '"Arbre"
                            g.DrawRectangle(Pens.Green, R)
                            g.FillRectangle(Brushes.Green, R)
                        Case 4 '"Sol"
                            g.DrawRectangle(Pens.Yellow, R)
                            g.FillRectangle(Brushes.Yellow, R)
                        Case 5 '"CoupeFeu"
                            g.DrawRectangle(Pens.Indigo, R)
                            g.FillRectangle(Brushes.Indigo, R)
                        Case 6 '"Eau"
                            g.DrawRectangle(Pens.Blue, R)
                            g.FillRectangle(Brushes.Blue, R)
                        Case Else
                            g.DrawRectangle(Pens.Blue, R)
                            g.FillRectangle(Brushes.Blue, R)
                    End Select
                    Me.PGB.Value += 1
                Next
                R.Offset(-R.Left, t)
            Next
        End Using
        Me.CreateGraphics.DrawImage(BackBuffer, 0, 0)


Pouvez-vous me dire ce qui cloche, svp?

Merci d'avance.
0
Spoonyx Messages postés 5 Date d'inscription vendredi 11 février 2011 Statut Membre Dernière intervention 2 janvier 2012
2 janv. 2012 à 15:47
Re,

J'ai fini par trouvé un moyen, je poste le code si sa peut interessé quelqu'un.
Dim BackBuffer As Image = New Bitmap(Me.ClientSize.Height, Me.ClientSize.Width)
        Using g As Graphics = Graphics.FromImage(BackBuffer)
            Dim i = 250
            Dim tableau(i, i) As Integer
            Dim t as double = (Me.ClientSize.height - 80) / i 'Calcul de la taille d'un côté de la figure en cases
            Dim R As New Rectangle(0, 20, t, t)
            Dim point As System.Drawing.Point
            For x As Integer = 0 To i - 1
                For z As Integer = 0 To i - 1
                    point.X = (z * t) + 20
                    point.Y = (x * t) + 20
                    R.Location = point
                    Select Case tableau(x, z)
                        Case 0 '"FeuG"
                            g.DrawRectangle(Pens.Silver, R) 'Affichage du rectangle
                            g.FillRectangle(Brushes.Silver, R) 'Remplissage du rectangle
                        Case 1 '"FeuR"
                            g.DrawRectangle(Pens.Red, R)
                            g.FillRectangle(Brushes.Red, R)
                        Case 2 '"Limite"
                            g.DrawRectangle(Pens.Orange, R)
                            g.FillRectangle(Brushes.Orange, R)
                        Case 3 '"Arbre"
                            g.DrawRectangle(Pens.Green, R)
                            g.FillRectangle(Brushes.Green, R)
                        Case 4 '"Sol"
                            g.DrawRectangle(Pens.Yellow, R)
                            g.FillRectangle(Brushes.Yellow, R)
                        Case 5 '"CoupeFeu"
                            g.DrawRectangle(Pens.Indigo, R)
                            g.FillRectangle(Brushes.Indigo, R)
                        Case 6 '"Eau"
                            g.DrawRectangle(Pens.Blue, R)
                            g.FillRectangle(Brushes.Blue, R)
                        Case Else
                            g.DrawRectangle(Pens.Blue, R)
                            g.FillRectangle(Brushes.Blue, R)
                    End Select
                Next
            Next
        End Using
        Me.CreateGraphics.DrawImage(BackBuffer, 0, 0)


Encore merci Renfield.
0
Rejoignez-nous