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

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

Renfield 17307 Messages postés mercredi 2 janvier 2002Date d'inscription 18 janvier 2017 Dernière intervention - 2 janv. 2012 à 12:42
+3
Utile
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
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Renfield
Renfield 17307 Messages postés mercredi 2 janvier 2002Date d'inscription 18 janvier 2017 Dernière intervention - 2 janv. 2012 à 12:27
0
Utile
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
Renfield 17307 Messages postés mercredi 2 janvier 2002Date d'inscription 18 janvier 2017 Dernière intervention - 2 janv. 2012 à 12:29
0
Utile
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
Spoonyx 5 Messages postés vendredi 11 février 2011Date d'inscription 2 janvier 2012 Dernière intervention - 2 janv. 2012 à 13:03
0
Utile
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
Renfield 17307 Messages postés mercredi 2 janvier 2002Date d'inscription 18 janvier 2017 Dernière intervention - 2 janv. 2012 à 13:07
0
Utile
Toi, t'as pas lu mon code...


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