Création de rectangles rapidement dans vb.net [Résolu]

Messages postés
5
Date d'inscription
vendredi 11 février 2011
Dernière intervention
2 janvier 2012
- 2 janv. 2012 à 12:17 - Dernière réponse :
Messages postés
5
Date d'inscription
vendredi 11 février 2011
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.
Afficher la suite 

Votre réponse

9 réponses

Meilleure réponse
Messages postés
17308
Date d'inscription
mercredi 2 janvier 2002
Dernière intervention
22 août 2018
2 janv. 2012 à 12:42
3
Merci
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

Merci Renfield 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 91 internautes ce mois-ci

Commenter la réponse de Renfield
Messages postés
17308
Date d'inscription
mercredi 2 janvier 2002
Dernière intervention
22 août 2018
2 janv. 2012 à 12:27
0
Merci
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
Commenter la réponse de Renfield
Messages postés
17308
Date d'inscription
mercredi 2 janvier 2002
Dernière intervention
22 août 2018
2 janv. 2012 à 12:29
0
Merci
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
Commenter la réponse de Renfield
Messages postés
5
Date d'inscription
vendredi 11 février 2011
Dernière intervention
2 janvier 2012
2 janv. 2012 à 13:03
0
Merci
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 !
Commenter la réponse de Spoonyx
Messages postés
17308
Date d'inscription
mercredi 2 janvier 2002
Dernière intervention
22 août 2018
2 janv. 2012 à 13:07
0
Merci
Toi, t'as pas lu mon code...


Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
Commenter la réponse de Renfield
Messages postés
5
Date d'inscription
vendredi 11 février 2011
Dernière intervention
2 janvier 2012
2 janv. 2012 à 13:18
0
Merci
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!
Commenter la réponse de Spoonyx
Messages postés
17308
Date d'inscription
mercredi 2 janvier 2002
Dernière intervention
22 août 2018
2 janv. 2012 à 14:50
0
Merci
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
Commenter la réponse de Renfield
Messages postés
5
Date d'inscription
vendredi 11 février 2011
Dernière intervention
2 janvier 2012
2 janv. 2012 à 14:53
0
Merci
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.
Commenter la réponse de Spoonyx
Messages postés
5
Date d'inscription
vendredi 11 février 2011
Dernière intervention
2 janvier 2012
2 janv. 2012 à 15:47
0
Merci
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.
Commenter la réponse de Spoonyx

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.