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 :

[POO] conception d'un logiciel de dessin vectoriel


Sujet :

VB.NET

  1. #1
    Membre à l'essai
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Points : 10
    Points
    10
    Par défaut [POO] conception d'un logiciel de dessin vectoriel
    Bonjour,

    J'esseye d'écrire un petit logiciel de dessin vectoriel en VB.NET (c'est en fait un soft que j'avais écrit en VB6 et qui tourne très bien ainsi d'ailleurs, très rapide, mais pour ma culture personnelle je souhaite le transposer en VB.NET)

    L'objectif est d'utiliser les fonctionalités .NET pour ce qui est du graphisme, mais aussi et surtout de faire ça proprement en utilisant la POO.

    En 2 mots, je souhaiterai créer une collection d'objets de types différents (des lignes, des cercles, des lignes de cotations, ...).

    Pour celà, j'ai créé mes classes d'objets, avec leur caractéristiques propres, par exemple :

    Code vb : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class_Line
      properties x1,y1,x2,y2
      method Draw
      ...
    class_Circle
      properties xCentre,yCentre,Rayon
      method Draw
      ...

    Ce que je ne sais pas, c'est lorsque ces objets ont des properties communes, par exemple la Couleur, ou l'Epaisseur du trait, ... dois-je les définir dans chaque classe, ou est-ce plus propre de définir une classe commune dont on pourrait en sorte hériter, et comment ?

    Ensuite, pour grouper mes objets, j'ai créé une collection, ou plus précisément une ArrayList (d'ailleur est-ce la meilleur solution et la plus rapide ?) :

    Code vb : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim myObjects As New ArrayList()

    et j'y ajoute mes objets ainsi :

    Code vb : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Dim newCircle As New class_Circle
    With newCircle
      .xCentre = ...
      .yCentre = ...
      .Rayon = ...
    End With
    myObjects.Add(newCircle)

    Donc déjà jusque là, suis-je à peu près ok ?

    Ensuite, lorsque je veux par exemple tout redessiner, je fais ainsi :

    Code vb : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    For i As Integer = 0 To myObjects.Count - 1
      Select Case myObjects(i).GetType.Name
         Case Is = "class_Line"
           CType(myObjects(i), class_Line).Draw(.....)
         Case Is = "class_Circle"
           CType(myObjects(i), class_Circle).Draw(.....)
      End Select
    Next

    Là par contre, je sens que vous allez tiquer... utiliser CType pour accéder aux methods propre à chaque classe, je ne trouve pas ça génial, mais je ne sais pas comment faire autrement ?

    Voilà, donc si vous avez la bonne marche à suivre, je suis preneur !

    Merci d'avance !!!
    Rod

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2007
    Messages : 127
    Points : 131
    Points
    131
    Par défaut
    Désolé je ne pourrais répondre qu'à ta première question
    il est clair qu'en utilisant la notion d'héritage ce sera plus propre et plus POO
    Pour cela créer toi une classe avec les propriétés qui te semble communes
    Ensuite tu fait un inherits dans ta classe ou tu veux t'en servir
    et après tu définieras ta var ou ta propriété avec ta classe. Tu pourras toujours faire un overrides de ta propriété ou de ta méthode si il y a des choses qui changent.
    Cela ne fait pas énormément de temps que je n'y suis mit, mais je le verrais plutôt comme ça. Mais je pense que si tu veux vraiment faire le la POO à fond avec ce type de projet, tu devrais te plonger un peu dans l'UML afin de voir comment vont s'agencer tes classes.
    Sinon je ne comprends pas ce que tu veut dire par grouper tes objets, que veux tu faire avec ça?
    Et pour le dernier point, si j'ai compris, tu accède aux méthodes de tes propres classes par un cType??
    Alors là, si j'ai bien compris, c'est clair que ça reste en travers de la gorge!!
    Quand tu as créer ta classe,as-tu créer un constructeur et un destructeur?
    bref, tu fais un Dim NomObjet as Nomdetaclasse
    et après tu obtiens toutes les méthodes et propriétés(propre à cet objet) en faisant : NomObjet.Nommethode ou nompropriete
    Comme tu te servirais de la classe string
    dim pidou as string = "blabla"
    pidou.replace("a","i")
    Bonne chance pour ton programme

    EDIT: abandonne le WITH
    c'est la même chose que ce que je viens de dire
    dim moncercle as new classe_circle
    moncercle.xcentre = mavaleur

  3. #3
    Membre à l'essai
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Points : 10
    Points
    10
    Par défaut
    merci de ta réponse mathrb

    effectivement c'est beaucoup plus propre ainsi :

    j'ai créé une classe "commune" avec les propriétés et methodes communes, que j'ai Inherité dans mes classes d'objets (j'ai eu un peu de mal à saisir la nuance entre private et protected)

    j'avais bien mis un constructeur New() mais je ne pensais pas qu'on pouvais y mettre des paramètres.... New(x1,y1, ...) c'est plus facile à utiliser

    quand je parle de grouper, je veux dire créer une collection ou une arrayList qui contiendrait mes objets lignes, cercles, ... que j'aurais créé

    merci en tout cas, j'avance...
    rod

  4. #4
    Membre chevronné
    Avatar de olsimare
    Inscrit en
    Décembre 2006
    Messages
    1 175
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 175
    Points : 1 767
    Points
    1 767
    Par défaut
    Bonjour.

    En lisant ce post, une question me vient.

    Pourquoi stocker les objets dans un collection ? Il me semblerait plus judicieux d'abonner les controls a un évènement .

    Exemple :
    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
     
    Public Class Form8
     
        Event redraw(ByVal g As Graphics)
     
        Public Sub New()
     
            ' Cet appel est requis par le Concepteur Windows Form.
            InitializeComponent()
     
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
     
            Dim c As New cercle(15, 15, 50, Color.Black, Color.Blue)
     
            AddHandler Me.redraw, AddressOf c.Draw
     
        End Sub
     
        Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
     
            RaiseEvent redraw(Me.CreateGraphics)
     
        End Sub
     
    End Class
     
    Public Class cercle
        Private wx As Integer
        Private wy As Integer
        Private wrayon As Integer
        Private wcolor1 As Color
        Private wcolor2 As Color
     
        Public Sub New(ByVal x As Integer, _
        ByVal y As Integer, _
        ByVal rayon As Integer, _
        ByVal color1 As Color, _
        ByVal color2 As Color)
            wx = x
            wy = y
            wrayon = rayon
            wcolor1 = color1
            wcolor2 = color2
        End Sub
     
        Public Sub Draw(ByVal g As Graphics)
            g.DrawEllipse(New Pen(wcolor1), New Rectangle(wx, wy, wrayon * 2, wrayon * 2))
            Dim c As Color
            c = wcolor1
            wcolor1 = wcolor2
            wcolor2 = c
        End Sub
    End Class
    A creuser peut être ...

    Cdt.
    Bon à savoir : la touche F1 ne sert pas à commander des places pour le grand prix de Belgique.

  5. #5
    Membre à l'essai
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Points : 10
    Points
    10
    Par défaut
    hello olsimare !

    ouahou, là je suis largué, j'ai du mal à comprendre comment ça marche, mais ça marche ! ça m'a l'air très intéressant cependant, car c'est vrai que la manipulation d'une collection est très lente

    par contre, peut-on naviguer parmis toutes les occurences ainsi créées, ou ne modifier qu'une instance en particulier ?

    et aussi est-ce plus gourmant en utilisation mémoire que d'utiliser des classes, imaginons un dessin composé de 1000 cercles ?

    as-tu un exemple d'appli un peu plus complète utilisant cette méthode ?

    en tous cas merci, une autre piste s'ouvre à moi.....

    a+
    Rod

  6. #6
    Membre chevronné
    Avatar de olsimare
    Inscrit en
    Décembre 2006
    Messages
    1 175
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 175
    Points : 1 767
    Points
    1 767
    Par défaut
    Bonjour.

    Par cette méthode, on cherche justement à éviter de naviguer entre les différents objets créés. Tout est fait dans l'objet lui même qui réagit à des sollicitations d'autres objets via des événements.

    Si tu veux naviguer, tu ne pourras pas te passer de la gestion d'une collection.

    Question performance, je ne connais pas la réponse, il faudrait bencher pour voir.

    Et non, je n'ai pas d'exemple d'appli la dessus !

    Si tu as vraiment beaucoup d'objets à gérer qui entraînent des problémes de perf, tu peux aussi creuser du côté du Flyweight (sous google on trouve pas mal de truc sur le sujet).

    Cdt.
    Bon à savoir : la touche F1 ne sert pas à commander des places pour le grand prix de Belgique.

  7. #7
    Membre à l'essai
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Points : 10
    Points
    10
    Par défaut
    je creuse et j'en reviens aux collections, car mon besoin l'impose je pense

    comme tout bon logiciel de dessin vectoriel, il me faut la possibilité de dessiner diverses formes (lignes, rectangles, cercles, ...) mais également de les grouper/dégrouper, les mettre par dessus/dessous...

    la notion de groupes de formes fait que nous pouvons modéliser ceci :

    dessin----(0,n)---->Groupes----(0,n)---->formes

    j'ai donc :
    - une classe dessin qui contient une arraylist de groupes
    - une classe groupe qui contient une arraylist de formes
    - des classes Ligne, Cercle, Rectangle ... avec des propriétés & méthodes propres mais aussi d'autres qui remplissent la même fonction (dessine, rotation, ...)

    ce qui me perturbe c'est de stocker différents types d'objets dans mon arraylist Groupes(), c'est à dire que je peux y trouver une instance Line, puis une instance Cercle, ...

    Dim c as New classeCercle(10,25,5)
    Groupes(7).Add c
    Dim r as New classeRectangle(71,45,15,10)
    Groupes(7).Add r

    et lorsque je défile le contenu d'un groupe avec un For each, je perds en fait le typage fort de chaque forme, je m'explique par l'exmple suivant, c'est comme ça que je fais pour le moment, ça marche mais ça ne me plais pas :

    dim obj as Object
    For each obj in Groupes(5)
    obj.dessine
    Next

    sachant que "dessine" est une méthode présente dans toutes les formes, mais elle ne m'est pas proposée automatiquement lors de la saisie de mon programme puisque obj est un object, non typé donc

    j'imagine que je ne devrais pas stocker directement mes instances de Lignes et autres Cercles dans mon groupe

    n'y a-t-il pas un moyen de définir une classe "forme", une sorte de chapeau contenant les propriétés et méthodes communes aux différentes formes....mais pouvant également hériter des particularité des formes élémentaires....oulà, là je me noye complètement !!!

    bref, vous voyez que là je sèche complètement, donc si quelqu'un pouvait m'expliquer de manière simple comment en POO on peut modéliser ce genre de problème, je suis preneur !

    merci de votre aide
    Rod

  8. #8
    Membre chevronné
    Avatar de olsimare
    Inscrit en
    Décembre 2006
    Messages
    1 175
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 175
    Points : 1 767
    Points
    1 767
    Par défaut
    Bonjour.

    Méthodes et propriétés communes mais avec des comportements bien différents (dessin d'un cercle, d'un rectangle ...), ça me fait penser à une interface tout ça...

    Donc pourquoi ne pas utiliser une interface plutôt qu'une class dont les formes héritent ?

    Exemple :
    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
     
    Option Explicit On
    Option Strict On
    Public Class Form8
     
        Dim al As New ArrayList
     
        Public Sub New()
            ' Cet appel est requis par le Concepteur Windows Form.
            InitializeComponent()
     
            al.Add(New formeCercle)
            al.Add(New formeCercle)
            al.Add(New formeRectangle)
            al.Add(New formeRectangle)
            al.Add(New formeCercle)
     
        End Sub
     
        Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
            For Each ifForme As IForme In al
                ifForme.Draw()
            Next
        End Sub
     
    End Class
     
    Public Interface IForme
        Sub Draw()
    End Interface
     
    Public Class formeCercle
        Implements IForme
        Public Sub Draw() Implements IForme.Draw
            ' Do something here
        End Sub
    End Class
    Public Class formeRectangle
        Implements IForme
        Public Sub Draw() Implements IForme.Draw
            ' Do something here
        End Sub
    End Class
    Du coup, tu accédes à toute les propriétés communes dés lors que tu cast les formes vers cette interface.

    Remarque que si tous les objets héritent d'un même objet formeDeBase par exemple, tu peux aussi faire :
    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
     
    Option Explicit On
    Option Strict On
    Public Class Form8
     
        Dim al As New ArrayList
     
        Public Sub New()
            ' Cet appel est requis par le Concepteur Windows Form.
            InitializeComponent()
     
            al.Add(New formeCercle)
            al.Add(New formeCercle)
            al.Add(New formeRectangle)
            al.Add(New formeRectangle)
            al.Add(New formeCercle)
     
        End Sub
     
        Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
            For Each ifForme As formeDeBase In al
                ifForme.draw()
            Next
        End Sub
     
    End Class
     
    Public MustInherit Class formeDeBase
        Public Overridable Sub draw()
            ' Do something here 
        End Sub
    End Class
     
    Public Class formeCercle
        Inherits formeDeBase
    End Class
    Public Class formeRectangle
        Inherits formeDeBase
        Public Overrides Sub Draw()
            ' Do something here
        End Sub
    End Class
    A voir.

    Cdt.
    Bon à savoir : la touche F1 ne sert pas à commander des places pour le grand prix de Belgique.

  9. #9
    Membre à l'essai
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Points : 10
    Points
    10
    Par défaut
    merci olsimare de ton aide
    j'en étais arrivé à ta 2ème méthode, et ça marche au poil !
    il me reste à implémenter la notion de groupes

    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
    Public MustInherit Class Shape
        Protected _pen As Pen
        Public MustOverride Sub draw(ByRef g As Graphics)
    End Class
     
    Public Class Line : Inherits Shape
        Private _x1, _y1, _x2, _y2 As Single
        Public Sub New(ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As Single, ByVal y2 As Single, ByVal pen As Pen)
            _x1 = x1
            _y1 = y1
            _x2 = x2
            _y2 = y2
            _pen = pen
        End Sub
        Public Overrides Sub Draw(ByRef g As Graphics)
            g.DrawLine(_pen, _x1, _y1, _x2, _y2)
        End Sub
    End Class
     
    Public Class Circle : Inherits Shape
        Private _xc, _yc, _ray As Single
        Public Sub New(ByVal xc As Single, ByVal yc As Single, ByVal ray As Single, ByVal pen As Pen)
            _xc = xc
            _yc = yc
            _ray = ray
            _pen = pen
        End Sub
        Public Overrides Sub Draw(ByRef g As Graphics)
            g.DrawEllipse(_pen, _xc - _ray, _yc - _ray, _ray * 2, _ray * 2)
        End Sub
    End Class
     
    Public Class Form1
        Private shapes As New System.Collections.ObjectModel.Collection(Of Shape)
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            shapes.Add(New Line(100, 100, 200, 200, Pens.Red))
            shapes.Add(New Circle(150, 150, 50, Pens.Blue))
            For Each shape As Shape In shapes
                shape.draw(Me.CreateGraphics)
            Next
        End Sub
    End Class

Discussions similaires

  1. logiciel de dessin vectoriel
    Par PoseurDeQuestion dans le forum Excel
    Réponses: 2
    Dernier message: 28/07/2012, 15h47
  2. Réponses: 0
    Dernier message: 26/03/2012, 11h30
  3. [Logiciels de dessin]Je recherche un logiciel ..
    Par arnaud_verlaine dans le forum Autres Logiciels
    Réponses: 5
    Dernier message: 17/01/2005, 13h58
  4. Dessin vectoriel
    Par Speed41 dans le forum Langage
    Réponses: 6
    Dernier message: 16/08/2004, 08h57
  5. [Info]Rectangles de sélection : logiciel de dessin ?
    Par rozwel dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 27/03/2004, 18h49

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