Arte generativa con FreeBASIC

Tutti sanno che nell’ottobre del 1917 ci fu una rivoluzione.

Fu proprio in quel mese, infatti, che uscì il primo numero della rivista Lo stile intorno alla quale si sviluppò il movimento artistico del neoplasticismo. Movimento che nel campo della pittura si basava su principi astratti e geometrici. Proprio per questo si fa riferimento al neoplasticismo anche definendolo astrattismo geometrico.

Tra i fondatori della rivista e del movimento ci fu il pittore Piet Mondrian le cui opere più famose sono composizioni dove compaiono soltanto linee nere orizzontali o verticali che dividono la tela in figure geometriche rettangolari o quadrate, alcune delle quali – la minoranza – sono colorate utilizzando soltanto i colori primari (rosso, giallo e blu). Molte parti, quindi, rimangono bianche.

Ma questo blog non parla di coding e del linguaggio di programmazione FreeBASIC? Cosa c’entra dunque l’arte?

In realtà esiste un elemento in comune tra queste due forme di espressione umana: la creatività.

Sebbene la creatività interessi molte fasi del ciclo della produzione del software (per esempio quella relativa al problem solving), qui vorrei concentrarmi soltanto su uno specifico campo di applicazione dello sviluppo del codice che è quello della cosiddetta Arte generativa: ovvero scrivere del codice che in maniera autonoma, o semi-autonoma, generi delle opere d’arte.

Generatore di immagini in stile Mondrian

Questo blog ha un taglio molto pratico e quindi vediamo subito insieme un esempio di come creare un piccolo programma in FreeBASIC che generi in maniera casuale – e quindi autonoma – delle immagini che richiamino almeno in parte lo stile di Mondrian.

Algoritmo

Ecco in sintesi i passi del nostro algoritmo:

  • Creare una finestra con l’istruzione screenres.
  • Inserire all’interno di un ciclo do-loop il codice per raccogliere l’input dell’utente attraverso l’istruzione getkey e poi con la struttura di controllo select case discriminare la prosecuzione delle operazioni:
    • In un caso disegnare le figure con l’istruzione line le cui dimensioni e colore sono definiti in maniera aleatoria attraverso l’istruzione rnd che genera un numero pseudo-casuale basato sull’algoritmo Mersenne Twister.
    • Nell’altro uscire dal programma.

Codice sorgente

''project:     mondrian.bas
''license:     GNU GPL v3
''version:     beta
''date:        September 20, 2020
''description: Mondrian style images generator
''author:      ciuco informatico
''web:         https://ciucoinformatico.home.blog/

dim as long key ''key entered

dim w as integer ''width of canvas
dim h as integer ''height of canvas

declare sub draw_image(w as integer, h as integer)

''canvas's size
w = 1000
h= 617

screenres w, h, 32
windowtitle("fb_mondrian.bas | Mondrian style images generator")

''color:
'' foreground: black
'' background: white
color(rgb(255,255,255),rgb(0,0,0))
cls

'menu
print "Press <Enter> to generate the image."
print "Press <Esc> to exit the programme."

''seeds the random number generator
randomize

do
  key = getkey

  select case key
    case 13 ''carriage return
      cls
      draw_image(w, h)
    case 27 '' quit
      exit do
    case else ''none
  end select

  ''to avoid unwanted or repeated characters,
  ''this loop works until the inkey buffer is empty
  while inkey <> "": wend
loop

''draws image
sub draw_image(w as integer, h as integer)
  dim free_w as integer '' free width
  dim free_h as integer ''free height
  dim as integer fill_color
  dim as integer x1, y1, x2, y2 = 0
  dim as integer margin = 10
  free_w = w
  free_h = h
  do
    y2 = int(rnd * h) + y1
    do
      x2 = int(rnd * w) + x1
      fill_color = int(rnd * 8) + 1
      select case fill_color
        case 1 ''yellow
          line(x1,y1)-(x2,y2),rgb(255,255,0),BF
        case 2 ''red
          line(x1,y1)-(x2,y2),rgb(255,0,0),BF
        case 3 ''blue
          line(x1,y1)-(x2,y2),rgb(0,0,255),BF
        case 4 to 8 ''white
          line(x1,y1)-(x2,y2),rgb(255,255,255),BF
        case else
      end select
      x1 = x2 + margin
    loop until x2 > w
    x1 = 0
    y1 = y2 + margin
  loop until y2 > h
end sub

Provate pure liberamente a modificarlo.

Ciao e al prossimo articolo. 🙂

FreeBASIC – Grafica [1]

E così siamo finalmente arrivati a parlare di grafica.

Disegnare delle semplici figure 2D sullo schermo e interagire con queste sarà l’obiettivo principale di questa nuova serie di articoli.

Come è ormai nostra abitudine, partiamo subito con qualcosa di concreto.

Come creare una finestra grafica

La prima cosa che ci serve è creare una finestra grafica su cui poi andremo a disegnare.

Per farlo si utilizza l’istruzione screen.

screen 16
print "Ecco la mia prima finestra grafica in"
print "modalita' 16: ovvero con risoluzione 512x384 pixels."
sleep 'istruzione per sospendere l'esecuzione del programma

Dare un titolo alla finestra grafica

Per abbellire la nostra finestra grafica diamole un titolo sfruttando la subroutine windowtitle:

windowtitle("La mia prima finestra")
screen 19
sleep

Modalità grafica

Il numero subito dopo l’istruzione screen definisce la modalità grafica (mode) sulla base delle seguenti due tabelle:

Le modalità dalla 1 alla 13 sono compatibili anche con i vecchi programmi scritti con il glorioso QuickBASIC, mentre le nuove modalità dalla 14 alla 21 sono specifiche del FreeBASIC. Sarà proprio su queste ultime che ci concentreremo.

Le due tabelle ci mostrano con chiarezza che più la modalità scelta sarà alta, più grandi saranno le dimensioni digitali della nostra finestra: ovvero la risoluzione dello schermo (resolution).

La dimensione digitale di uno schermo (nel nostro caso della finestra) è espressa come numero di pixels orizzontali e verticali (p.e. 512×384).

Scriviamo ora un semplice programma per visualizzare una finestra in tutte e sedici le diverse modalità. Per farlo sfrutteremo un array e un ciclo for.

'dimensiona un array con tutte le modalità grafiche
 dim mode_array (1 to 16) as integer

 'assegna i valori
 mode_array(1) = 1
 mode_array(2) = 2
 mode_array(3) = 7
 mode_array(4) = 8
 mode_array(5) = 9
 mode_array(6) = 11
 mode_array(7) = 12
 mode_array(8) = 13
 mode_array(9) = 14
 mode_array(10) = 15
 mode_array(11) = 16
 mode_array(12) = 17
 mode_array(13) = 18
 mode_array(14) = 19
 mode_array(15) = 20
 mode_array(16) = 21

 'visualizza con un ciclo le varie finestre
 for i as integer = lbound(mode_array) to ubound(mode_array)
   screen mode_array(i)
   print "Finestra grafica in modalita': "; mode_array(i)
   print "---"
   print "premi un taso per continuare…"
   sleep 'sospende l'esecuzione del programma
 next i

Funzione screenres

Le modalità grafiche che abbiamo visto hanno delle dimensioni digitali preimpostate, ma se volessimo creare una finestra grafica di dimensioni diverse?

Niente panico! FreeBASIC viene in nostro aiuto con la funzione screenres che ci permette proprio di definire le dimensioni digitali che vogliamo.

Questa funzione restituisce il valore 0 (zero) se le dimensioni digitali specificate sono realizzabili dal nostro computer, altrimenti viene restituito un numero che specifica il tipo di errore.

Per approfondire l’argomento vai all’articolo dedicato alla gestione degli errori.

Dopo aver provato il codice più sotto, provate a specificare per esempio un numero negativo come larghezza o come altezza:

''crea una finestra grafica larga 800px e alta 50px 
select case screenres(800,50)
  case 0 ''tutto OK
    print "Ecco una strana finestra grafica!"
  case else ''errore
    beep
    print "Non posso creare la finestra grafica che desideri."
end select
sleep ''rimani in pausa

Bene. Per oggi ci fermiamo qui.

Nel prossimo articolo parleremo della risoluzione grafica: ovvero della qualità delle immagini. 🙂