A partire dal modulo per la grafica del prof. John
M. Zelle Ph. D. Wartburg College (graphics.py manualetto dello stesso autore graphics.pdf)
è possibile ampliare le capacità grafiche alla grafica
della tartaruga sia nel piano che nello spazio.
Nel modulo graftarta2.py si definisce una classe
Graf che discende dalla classe GraphWin del modulo graphics.py e che
quindi gode di tutti i metodi definiti per
quest'ultima e che si
possono ritrovare nel manualetto graphics.pdf .
Per utilizzare la classe Graf bisogna innanzitutto
importarla:
from graftarta2 import Graf
Sarà allora possibile ottenere una istanza della classe
scrivendo ad esempio: t=Graf("nome",
600,400)
Si ottiene una finestra grafica con il titolo "nome" e di dimensioni
600X400 pixels su cui poter eseguire i grafici che interessano.
Le coordinate cartesiane di questa finestra sono
quelle "elettroniche" con l'origine nel vertice in alto a sinistra e
l'asse y diretto verso il basso. Per ottenere un riferimento cartesiano
classico con l'asse y diretto verso "l'alto", si può utilizzare
il metodo "coordinate" della classe Graf: t.coordinate(-50,-40,50,40)
in questo modo si avrà un riferimento cartesiano con le x che
variano da -50 a +50 e le y da -40 a +40 con gli assi orientati come
solitamente si fa nella didattica della matematica e della fisica. t.coordinate(-50,-40,50,40,True)
E' possibile ottenere il disegno degli assi e delle
tacche di numerazione semplicemente aggiungendo True:
Nel linguaggio Python è possibile infatti scrivere delle
funzioni che abbiano un numero variabile di parametri con la condizione
che i parametri facoltativi seguano quelli obbligatori e che i
parametri facoltativi abbiano comunque un valore anche quando non li si
richiami nella esecuzione. Ecco la prima riga della definizione del
metodo: def coordinate(self,
xi,yi,xs,ys,assi=False)
self sta ad indicare l'istanza della classe, poi abbiamo xinferiore,
yinferiore, xsuperiore, ysuperiore (vertici in basso a sinistra e in
alto a destra della finestra), il valore automaticamente assegnato ad
assi è False. Se invece si aggiunge True come nell'esempio
precedente, la stessa funzione esegue il disegno degli assi.
Volendo adesso eseguire il grafico di una funzione continua si
può utilizzare il metodo della classe Graf chiamato grafico:
def
grafico(self,f,xi,xs,passo=0.5):
"""grafico di f fra xinf e xsup"""
Una volta definita la funzione f, considerando l'istanza t di Graf,
come sopra, si può eseguire il grafico con:
t.grafico(f,xi,xs)
Se si vuole disegnare un punto, si può ricorrere ad un metodo
ereditato dalla classe GraphWin chiamato plot:
t.plot(x,y,"red")
Il riferimento cartesiano è quello stabilito dal metodo coordinate illustrato
sopra.
Se si vuole disegnare un segmento, si può fare ricorso
all'oggetto grafico Line(Point1,Point2) facente parte come GraphWin del
modulo graphics.py del prof. John
M. Zelle. Per usare gli oggetti grafici di tale modulo si deve scrivere:
from graphics
import *
cioè importa tutte le classi definite in graphics
Per disegnare il segmanto si può scrivere:
nella seconda riga, t è l'istanza della classe Graf come
definito prima.
Grafica della tartaruga
Accanto alla tradizionale grafica
cartesiana, si è ultimamente aggiunta una nuova forma di
grafica: la
"grafica della tartaruga". Con questo termine ci si riferisce ai
grafici
ottenuti utilizzando un automa (detto tartaruga) che può essere
un vero
robot che disegna sul pavimento o più modestamente un
triangolino sullo
schermo che obbedisce ad un repertorio di primitive per disegnare sullo
schermo. Sostanzialmente delle primitive di traslazione che lasciano
una scia colorata sullo schermo (avanti (dist), assegnaPosizione
asPos(x,y)) o delle primitive di rotazione (destra (ang), assegna
direzione asDir(ang) ) che cambiano la direzione verso cui
"punta" la tartaruga la sua orientazione.
Per realizzare dei programmi
significativi si deve porre grande attenzione allo stato della
tartaruga (sostanzialmente posizione e direzione).
La grafica della tartaruga è un
modo
divertente per esplorare la matematica, l'informatica, ma anche per
costruire piccole simulazioni in fisica ed anche in altre scienze.
L'automa tartaruga è stato inventato da S. Papert ed è
stato utilizzato
praticamente in tutto il mondo nella didattica a tutti i livelli da
quelli più elementari fino a quelli universitari.
Un libro che ha segnato una tappa
fondamentale è l'interessantissimo:
"La geometria della tartaruga" di H.
Abelson e A. Di Sessa ed. Muzzio
Ricchi di suggerimenti ed idee
didatticamente valide sono i due volumi:
"Fisica e Informatica" di M.V. Cecchet e
P. Peranzoni ed. Cedam
Esempio:
from graftarta2 import
Graf t=Graf("prova",
500, 300) t.coordinate(-250,-180,250,180) def quadrato(lato):
for k in range(4):
t.avanti(lato)
t.destra(90) quadrato(100) quadrato(50)
Si importa il modulo graftarta2 e si scrive la funzione
che
definisce il quadrato dando come parametro formale il lato. Dopo i due
punti, rientro e inizia un ciclo di ripetizioni for con ulteriore
rientro. Range(4) origina
una lista ordinata di naturali da 0 a 3. In altre parole ripeti quattro
volte avanti(lato) e sinistra(90). Da notare che t.destra(90) inizia
con la stessa colonna di t.avanti(lato).
Per eseguire il programma dalla IDLE si può
utilizzare il menù RUN e poi RUN MODULE
Per disegnare poligoni regolari e
"stelle" con i lati intrecciati
def
poli(lato, angolo):
t.avanti(lato)
t.destra(angolo)
somma = angolo
while somma % 360 != 0:
t.avanti(lato)
t.destra(angolo)
somma = somma+angolo
La variabile somma serve a
memorizzare l'angolo totale di cui ruota la tartaruga. Se questa somma
di angoli forma un angolo di 360 (o un suo multiplo intero) il poligono
è completo. Per verificare ciò si utilizza il modulo 360
ovvero il
resto nella divisione intera per 360 (nel Python si indica con %). Se
il modulo somma % 360 è diverso da zero si manda avanti la
tartaruga e
la si fa girare ogni volta di un certo angolo. Se questo modulo
è zero
il ciclo while si interrompe.
Si possono eseguire i
grafici dei poligoni
eseguendo tale funzione con valori diversi dell'angolo che in
realtà è
l'angolo esterno del poligono. Ad esempio poli(lato,72) esegue un
pentagono. Poli(lato,144) la stella a cinque punte.
Un esempio di quadrato ricorsivo:
def quaric(lato):
if lato > 4:
for n in range(4):
t.avanti(lato)
quaric(lato/2)
t.destra(90)
E' possibile utilizzare l'automa tartaruga per delle
piccole simulazioni di Fisica.
I rimbalzi di una palla sono un buon esempio di questo tipo di
simulazioni.
E' naturale eseguire il grafico delle energie che intervengono nella
simulazione per mettere in evidenza la diminuizione dell' energia
totale ad ogni rimbalzo:
Seguendo la linea descritta da Abelson e Di Sessa ne
"La Geometria della tartaruga" ed. Muzzio è possibile
dotare la tartaruga delle primitive per farla muovere nello spazio a
tre dimensioni.
Dodecagono (dodici facce che sono
pentagoni regolari uguali) disegnato
con la grafica della tartaruga.
Primitive per la tartaruga spaziale
Per la rotazione nel piano sono sufficienti i soli comandi Destra(Angolo)
e Sinistra(Angolo); nello spazio la situazione diventa
molto più complessa.
Si può immaginare la tartaruga spaziale associata ad
una
terna sinistrorsa di versori mutuamente perpendicolari: basta
pensare al dito medio, indice e pollice della mano sinistra.
Adesso per definire le rotazioni si immagina di lasciare invariato
uno solo
di questi versori alla volta e di far ruotare gli altri due in un
piano perpendicolare a quello rimasto
fisso. Per dare un nome a queste rotazioni si può far ricorso
a tre termini aeronautici:
Beccheggia(angolo)
E’ il movimento
che consiste nel tenere fisso il pollice e nel ruotare le altre
due dita, per analogia al movimento delle le galline quando beccano.
Analogamente con il comando Imbarda(angolo)
resta fisso
l'indice e ruotano le altre due dita, mentre con
Rolla(angolo)
resta fisso il medio e ruotano le altre due dita.
Dopo aver
così
stabilito le tre primitive per le rotazioni nello spazio, si
stabilisce che la traslazione della tartaruga si
realizzi nella direzione individuata dal dito medio con il comando avanti3d
(per distinguersi da Avanti valido nel piano). Con il corredo di
queste quattro primitive è possibile eseguire disegni nelle
tre dimensioni senza la necessità di far ricorso alle
coordinate cartesiane dei punti. Questo aspetto rende la “Geometria
della tartaruga” molto interessante sia dal punto di vista
matematico sia didattico che informatico.
Per fare un esempio
sul
modo di eseguire disegni nelle tre dimensioni ecco di seguito il
listato di due procedure. La prima serve a disegnare un rettangolo di
dimensioni lato1 ed lato2.
Questa procedura viene utilizzata dalla procedura parallelepipedo che
ha come scopo quello di disegnare un parallelepipedo di dimensioni a,
b, c.:
def rettangolo(lato1,lato2,t):
for k in range(2):
t.avanti3d(lato1)
t.imbarda(math.pi/2)
t.avanti3d(lato2)
t.imbarda(math.pi/2)
In rosso il rettangolo definito prima
def parallelepipedo(a,b,c):
t.rolla(math.pi/2)
for k in range(2):
rettangolo(a,c,t)
t.pennasu()
t.avanti3d(a)
t.pennagiu()
t.beccheggia(-math.pi/2)
L’esecuzione del
rettangolo si basa sul ripetere due volte un certo insieme di
istruzioni: andare avanti di lato1, imbardare di un angolo retto (dove
Pi ha il significato di P greco), andare avanti di lato2, imbardare di
un angolo retto. Analogamente anche la procedura parallelepipedo
sfrutta la ripetizione due volte dello stesso insieme di istruzioni.
Un aspetto importante delle procedure è che bisogna porre
attenzione affinché lo stato della tartaruga (sostanzialmente
direzione e posizione) rimanga invariato dopo l’esecuzione di
ciascuna procedura. Ad esempio nella procedura rettangolo la
rotazione totale dovuta a quattro volte imbarda(Pi/2), corrisponde ad
un angolo giro cioè la tartaruga riassume lo stesso
orientamento iniziale. Anche nella procedura parallelepipedo, alla
rotazione iniziale rolla(Pi/2) corrisponde alla fine una rotazione
opposta rolla(-Pi/2) che riporta lo stato della tartaruga alla
situazione iniziale
Due ottaedri regolari (ciascuno ha
otto facce formate da triangoli equilateri uguali)
Icosaedro regolare (20 facce formate
da triangoli equilateri
uguali)
Tre tetraedri (quattro facce formate
da triangoli equilateri
uguali)
Tre cubi
La definizione di cubo è la seguente:
def cubo(lato,t):
for j in range(4):
for k in range(4):
t.avanti3d(lato)
t.beccheggia(math.pi/2)
t.avanti3d(lato)
t.imbarda(math.pi/2)
E' chiaro che una volta definito in generale il cubo sarà
possibile disegnare qualunque cubo al variare del lato e dello stato
iniziale della tartaruga.
Cubo ricorsivo
Con una chiamata ricorsiva (cuboric(lato/4.0,t)) inserita nella
definizione di cubo si ottiene il grafico precedente:
def
cuboric(lato,t):
if lato>0.2:
for j in range(4):
for k in range(4):
t.avanti3d(lato)
t.beccheggia(math.pi/2)
cuboric(lato/4.0,t)
t.avanti3d(lato)
t.imbarda(math.pi/2)
Le definizioni per i poliedri regolari con cui sono stati
eseguiti i grafici precedenti sono complessee
si trovano nel file cub2.txt
Il grafico in tre dimensioni di una
gaussiana
Per eseguire i grafici cartesiani nelle tre dimensioni è stato
definito un metodo della classe Graf chiamato
disegnapunto3d(a,b,c,colore) che disegna un punto colorato sullo
schermo di coordinate (a,b,c).
Le linee rosse sono state ottenute fissando la terza coordinata (la z)
e facendo variare le x. Mentre le linee verdi sono state ottenute
fissando la x e facendo variare la z. La y viene calcolata come
funzione di due variabili x e z.
Grafica nelle due dimensioni
Metodi della classe Graf
def coordinate(self,
xi,yi,xs,ys,assi=False):
""" stabilisce le coordinate cartesiane per la finestra grafica
xi yi coord. vertice in basso a sinistra
xs ys coord. vertice in alto a destra
ovvero le x nell'intervallo xinferiore, xsuperiore
le y nell'intervallo yinferiore ysuperiore
se si pone assi True, disegna gli assi e le tacche """
def
__init__(self,title="Graphics Window",width=200, height=200,
autoflush=False):
""" la classe Graf discende dalla classe GraphWin del modulo
graphics """
Utilizzando il modulo graphics (graphics.py
del dott. Zelle, manualetto dello stesso autore graphics.pdf)
è possibile utilizzare una funzione chiamata color_rgb(...)
che riporta il "nome" di un colore assegnati i valori di rosso, verde e
blu (RGB), ciascuno variabile fra 0 e 255. Il metodo
random.randint(n_iniz, n_fin) (modulo
random) restituisce un intero casualmente scelto fra n_iniz ed
n_fin, estremi compresi. Per semplificare la scrittura è
possibile in Python una cosa prodigiosa e cioè definire un
letterale e porlo uguale al nome del metodo ad esempio: