venerdì 19 novembre 2010

Esercizio 2 (word cloud) - Enrico Scafà , Carlo Giustiniani

Imports System.Drawing.Drawing2D

Public Class Form1


    Public PaoleDaIgnorare As Dictionary(Of String, Boolean)

    Public ListaColori As List(Of Color)

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        PaoleDaIgnorare = New Dictionary(Of String, Boolean)(StringComparer.InvariantCultureIgnoreCase)

        Me.PaoleDaIgnorare.Add(" I ", Nothing)
        Me.PaoleDaIgnorare.Add(" IL ", Nothing)
        Me.PaoleDaIgnorare.Add(" LA ", Nothing)
        Me.PaoleDaIgnorare.Add(" LE ", Nothing)
        Me.PaoleDaIgnorare.Add(" GLI ", Nothing)
        Me.PaoleDaIgnorare.Add(" IN ", Nothing)
        Me.PaoleDaIgnorare.Add(" CON ", Nothing)
        Me.PaoleDaIgnorare.Add(" SU ", Nothing)
        Me.PaoleDaIgnorare.Add(" PER ", Nothing)
        Me.PaoleDaIgnorare.Add(" TRA ", Nothing)
        Me.PaoleDaIgnorare.Add(" FRA ", Nothing)
        Me.PaoleDaIgnorare.Add(" UN ", Nothing)
        Me.PaoleDaIgnorare.Add(" UNO ", Nothing)
        Me.PaoleDaIgnorare.Add(" UNA ", Nothing)
        Me.PaoleDaIgnorare.Add(" O ", Nothing)
        Me.PaoleDaIgnorare.Add(" A ", Nothing)


        ListaColori = New List(Of Color)
        ListaColori.Add(Color.Beige)
        ListaColori.Add(Color.BlueViolet)
        ListaColori.Add(Color.Coral)
        ListaColori.Add(Color.CornflowerBlue)
        ListaColori.Add(Color.Aquamarine)
        ListaColori.Add(Color.DarkCyan)
        ListaColori.Add(Color.DarkRed)
        ListaColori.Add(Color.DodgerBlue)
        ListaColori.Add(Color.Firebrick)
        ListaColori.Add(Color.Chartreuse)
        ListaColori.Add(Color.DarkSlateBlue)
        ListaColori.Add(Color.Aquamarine)
        ListaColori.Add(Color.AliceBlue)
        ListaColori.Add(Color.Beige)
        ListaColori.Add(Color.BlueViolet)
        ListaColori.Add(Color.Coral)
        ListaColori.Add(Color.CornflowerBlue)
        ListaColori.Add(Color.Aquamarine)
        ListaColori.Add(Color.DarkCyan)
        ListaColori.Add(Color.BlueViolet)
        ListaColori.Add(Color.Coral)
        ListaColori.Add(Color.CornflowerBlue)
        ListaColori.Add(Color.Aquamarine)
        ListaColori.Add(Color.DarkCyan)
        ListaColori.Add(Color.DarkRed)
        ListaColori.Add(Color.DodgerBlue)
        ListaColori.Add(Color.Firebrick)
        ListaColori.Add(Color.Chartreuse)
        ListaColori.Add(Color.DarkSlateBlue)
        ListaColori.Add(Color.Aquamarine)
        ListaColori.Add(Color.AliceBlue)
        ListaColori.Add(Color.Beige)
        ListaColori.Add(Color.BlueViolet)
        ListaColori.Add(Color.Coral)
        ListaColori.Add(Color.CornflowerBlue)
        ListaColori.Add(Color.Aquamarine)
        ListaColori.Add(Color.DarkCyan)



    End Sub


    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim Corpus As String = Me.RichTextBox1.Text
        Dim Corpus_Normalizzato As String = Corpus.ToUpper.Replace(",", " ").Replace(vbCrLf, " ").Replace("!", " ").Replace("  ", " ")

        For Each PaolaDaRimuovere As String In Me.PaoleDaIgnorare.Keys
            Corpus_Normalizzato = Corpus_Normalizzato.Replace(PaolaDaRimuovere, " ")
        Next PaolaDaRimuovere
        Corpus_Normalizzato = Corpus_Normalizzato.Replace("  ", " ")

        Me.RichTextBox2.Text = Corpus_Normalizzato

        Dim Parole As String() = Corpus_Normalizzato.Split((vbCrLf & " ").ToArray, StringSplitOptions.RemoveEmptyEntries)

        Dim ListaParoleDiverse As New Dictionary(Of String, InfoParola)(StringComparer.InvariantCultureIgnoreCase)

        For Each parola As String In Parole

            If Me.PaoleDaIgnorare.ContainsKey(parola) Then Continue For
            If parola.Trim = "" Then Continue For

            If ListaParoleDiverse.ContainsKey(parola) Then
                Dim InfoParola As InfoParola = ListaParoleDiverse(parola)
                InfoParola.FrequenzaAssoluta += 1
            Else
                Dim InfoParola As New InfoParola
                InfoParola.Parola = parola
                InfoParola.FrequenzaAssoluta = 1
                ListaParoleDiverse.Add(parola, InfoParola)
            End If

        Next parola

        Dim NumeroParoleTotale = Parole.Count
        Dim NumeroParoleDiverse = ListaParoleDiverse.Count

        Me.LabelCorpus.Text = "CORPUS [" & NumeroParoleDiverse & " / " & NumeroParoleTotale & "]"


        Me.CreaWordCloud(ListaParoleDiverse)

    End Sub


    Sub CreaWordCloud(ByVal ListaParoleDiverse As Dictionary(Of String, InfoParola))

        Dim rnd As New Random
        Dim b As New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height)
        Dim g As Graphics = Graphics.FromImage(b)

        'Disegnare ...

        'Determiniamo l'ingombro di ciascuna parola se rappresentata con un font proporzionale alla frequenza

        Dim MinimaDimensioneFont As Integer = 8
        Dim MassimaDimensioneFont As Integer = 50
        Dim MinFrequenza = Integer.MaxValue
        Dim MaxFrequenza = Integer.MinValue

        'Determiniamo la minima e massima frequenza
        For Each InfoParola As InfoParola In ListaParoleDiverse.Values
            If MinFrequenza > InfoParola.FrequenzaAssoluta Then MinFrequenza = InfoParola.FrequenzaAssoluta
            If MaxFrequenza < InfoParola.FrequenzaAssoluta Then MaxFrequenza = InfoParola.FrequenzaAssoluta
        Next InfoParola

   
        Dim FontProporzionato As Font

        'Determiniamo la dimensione del font corrispondente alla frequenza
        Dim i As Integer = 0
        Dim stampata As Boolean
        Dim PathRettangoli As New GraphicsPath

        For Each InfoParola As InfoParola In ListaParoleDiverse.Values

            stampata = False

            With InfoParola
                .DimensioneDelFontCorrispondenteAllaFrequenza = CSng(MinimaDimensioneFont + (.FrequenzaAssoluta - MinFrequenza) * (MassimaDimensioneFont - MinimaDimensioneFont) / (MaxFrequenza - MinFrequenza))
                FontProporzionato = New Font("Arial", .DimensioneDelFontCorrispondenteAllaFrequenza, FontStyle.Regular, GraphicsUnit.Pixel)

                Dim Size As SizeF = g.MeasureString(.Parola, FontProporzionato, Point.Empty, StringFormat.GenericDefault)
                .LarghezzaParola = Size.Width
                .AltezzaPaola = Size.Height

                '--colore_casuale--
                Dim colorNames As String() = System.Enum.GetNames(GetType(KnownColor))
                Dim lstColors As New List(Of String)(colorNames)
                lstColors.Remove("Black")

                Dim IndiceCasuale As Integer = rnd.Next(0, lstColors.Count - 1)
                .Colore = System.Drawing.Color.FromName(lstColors(IndiceCasuale))

                'STAMPARE LE PAROLE

                Dim SIzeFString As SizeF = g.MeasureString(.Parola, FontProporzionato) 'misuar la grandezza della stringa con quel font

                'random
                Dim n_casuale As Double = rnd.NextDouble
                Dim raggio1 As Double = Math.Min(b.Width, b.Height) / 2
                Dim raggio2 As Double = Math.Min(b.Width, b.Height) / 3

                Do While stampata = False

                    Dim angoloCasuale As Double = rnd.NextDouble * 2 * Math.PI
                    Dim distanzaCasuale As Double = rnd.NextDouble * raggio1
                    Dim distanzaCasuale2 As Double = rnd.NextDouble * raggio2

                    Dim x As Double
                    Dim y As Double

                    If i Mod 3 = 0 Then
                        x = b.Width / 2 + Math.Cos(angoloCasuale) * distanzaCasuale
                        y = b.Height / 2 + Math.Sin(angoloCasuale) * distanzaCasuale
                        ' g.RotateTransform(rnd.Next(-3, 3))
                    End If
                    If i Mod 3 = 1 Then

                        x = b.Width / 4 + Math.Cos(angoloCasuale) * distanzaCasuale2
                        y = b.Height / 2 + Math.Sin(angoloCasuale) * distanzaCasuale2

                        ' g.RotateTransform(-rnd.Next(5, 30))
                    End If
                    If i Mod 3 = 2 Then

                        x = b.Width * 3 / 4 + Math.Cos(angoloCasuale) * distanzaCasuale2
                        y = b.Height / 2 + Math.Sin(angoloCasuale) * distanzaCasuale2
                        ' g.RotateTransform(rnd.Next(5, 30))
                    End If

                    Dim RettangoloStringa As New Rectangle(New Point(x, y), SIzeFString.ToSize)

                    Dim R As New Region(PathRettangoli)

                    If Not R.IsVisible(RettangoloStringa) Then 'verifico se il nuovo rettangololstringa si sovrappone alla parte già esistente
                        g.DrawString(.Parola, FontProporzionato, New SolidBrush(.Colore), x, y)
                        stampata = True

                        PathRettangoli.AddRectangle(RettangoloStringa)
                    End If




                Loop


              
                ' g.ResetTransform()


            End With
            i += 1

        Next InfoParola

        Me.PictureBox1.Image = b

    End Sub


End Class

Public Class InfoParola

    Public x As Integer
    Public y As Integer

    Function RettangoloOccupato() As Rectangle
        Return New Rectangle(x, y, CInt(Me.LarghezzaParola), CInt(Me.AltezzaPaola))


    End Function

    Public Parola As String
    Public FrequenzaAssoluta As Integer

    Public DimensioneDelFontCorrispondenteAllaFrequenza As Single
    Public LarghezzaParola As Single
    Public AltezzaPaola As Single

    Public Colore As Color

    Dim r As Rectangle



End Class




Nessun commento:

Posta un commento

Nota. Solo i membri di questo blog possono postare un commento.