Scarica fab2.ps
% (fab2.ps) (r) file run
%
% Fabbrica dei giocattoli versione 0.2
% (C) 2008 Marco Bisetto
% Released under the terms of GNU GPL version 2
%
% Questo programma in PostScript genera gli ottantuno giocattoli
% matriciali del professor Francis Sullivan, mostrandoli in una matrice
% 9*9 di grafici su un foglio di dimensioni A4. Le matrici vengono
% applicate su una figura chirale, cosi` si possono apprezzare tutte
% le trasformazioni geometriche. La figura di partenza e` nel quadrante
% a nordest della mappa, ovviamente associata alla matrice unitaria.
%
% PostScript ha le primitive giuste per questo tipo di applicazione. Lo
% spazio utente di PostScript e` uno spazio affine associato allo spazio
% vettoriale R^2. E` gia` definita una matrice 3*3 chiamata CTM, Current
% Transformation Matrix, che permette cambiamenti di base e traslazioni
% nello spazio utente. Da notare che PostScript usa vettori riga, quindi
% la CTM e` trasposta rispetto ai vettori colonna che noi usiamo. La CTM
% e` definita nel seguente modo:
%
% / b00 b01 0 \
% | |
% | b10 b11 0 |
% | |
% \ tx ty 1 /
%
% Il vettore (x, y, 1) viene quindi trasformato nel seguente modo:
%
% (x, y, 1) * CTM = (x*b00 + y*b01 + tx, x*b01 + y*b11 + ty, 1)
%
% Da notare che PostScript usa la meravigliosa RPN (notazione polacca
% inversa) ben nota agli amanti delle calcolatrici scientifiche HP. Gli
% operandi vengono spinti su una pila e quindi viene chiamato un
% operatore che li utilizza e pone il risultato nuovamente in cima alla
% pila. Vale la pena di giocare un po' con l'interprete solo per
% il piacere che da` il linguaggio di programmazione.
%
% ESP Ghostscript versione 8.15.3 presenta un bug nell'utilizzo della
% CTM, e in alcuni casi produce degli overflow. Per cui ho aggiunto un
% hack che moltiplica le coordinate per la matrice di trasformazione
% 2*2, in questo caso utilizzando la convenzione dei vettori colonna e
% trascurando ovviamente la traslazione, che produco comunque con la CTM
% usando l'istruzione translate. Sui grafici le matrici sono
% rappresentate sempre usando la convenzione dei vettori colonna, come
% visto a lezione.
%
% GPL Ghostscript versione 8.54 non presenta lo stesso bug, per cui e`
% possibile decommentare l'hack e utilizzare la CTM.
%
% Se avete altri interpreti PostScript, fatemi sapere il risultato.
%
% Qualora non siate pratici nell'uso di interpreti PostScript, un
% comando preconfezionato per produrre un file pdf con Ghostscript
% e` il seguente:
%
% gs -sDEVICE=pdfwrite -sPAPERSIZE=a4 -sOutputFile=giocattoli.pdf fab2.ps
%
% Su sistemi UNIX like potete usare direttamente gv per mostrare sullo
% schermo il risultato:
%
% gv fab2.ps
%
% N.B. Poiche' le righe dei casi degeneri sono molto sottili, dovete
% disabilitare l'antialias e usare un opportuno ingrandimento. In gv si
% trova nel menu` State. In acrobat disabilitate:
% Edit->Preferences...->Smooth line art. Con xpdf si vede bene.
%
% Se volete giocare con PostScript ecco la bibliografia:
%
% titolo: PostScript language
% sottotitolo: Tutorial and Cookbook
% autore: Adobe Systems Incorporated
% editore: Addison-Wesley
% (denominato Blue Book)
%
% titolo: PostScript language reference
% autore: Adobe Systems Incorporated
% editore: Addison-Wesley
% (denominato Red Book)
%
% Buon divertimento.
%
% Marco
%
/points 12 def
/symbolfont
/Symbol findfont points scalefont
def
/textfont
/Times-Roman findfont points scalefont
def
/symbolmode { symbolfont setfont } def
/textmode { textfont setfont } def
/xc 620 10 div def % stepX
/yc 620 2 sqrt mul 10.5 div def % stepY
/r xc 3 div def % axes radius
/r10 r 10 div def
/block { % - block - : to use with PostScript CTM
newpath
r10 dup moveto
r10 9 mul r10 lineto
r10 9 mul r10 3 mul lineto
r10 7 mul r10 3 mul lineto
r10 7 mul r10 7 mul lineto
r10 r10 7 mul lineto
%r10 r10 lineto
%stroke
closepath fill
} def
/matprod { % x y matprod - : 2*2 transformation matrix for column vector
1 index a00 mul 1 index a01 mul add
3 -1 roll a10 mul 3 -1 roll a11 mul add
} def
/blockh { % - blockh - : hacked for gs-esp transformation bug
newpath
r10 dup matprod moveto
r10 9 mul r10 matprod lineto
r10 9 mul r10 3 mul matprod lineto
r10 7 mul r10 3 mul matprod lineto
r10 7 mul r10 7 mul matprod lineto
r10 r10 7 mul matprod lineto
%r10 r10 matprod lineto
%stroke
closepath fill
} def
/stmp 2 string def
/numshow { % number numshow - : print right justified signed number
stmp cvs
dup stringwidth pop points sub neg 0 rmoveto
show
} def
/morigin { % - morigin - : origin of matrix representation
xc 2 div neg yc 2 div neg moveto
} def
/paren { % - paren - : print matrix parentheses
symbolmode
morigin
(\350) show
morigin 0 points rmoveto
(\346) show
morigin points 2 mul 0 rmoveto
(\370) show
morigin points 2 mul points rmoveto
(\366) show
textmode
} def
/matr { % number X Y matr - : print matrix element in its position
morigin
points 4 div 0 rmoveto
points mul % X = col
exch
1 sub neg
points mul % Y = row
rmoveto
numshow
} def
/axes { % - axes -
0.95 setgray
newpath r neg 0 moveto r 0 lineto stroke % Y axis
newpath 0 r neg moveto 0 r lineto stroke % X axis
0 setgray
} def
gsave
-1 1 1 { /a00 exch def
-1 1 1 { /a01 exch def
-1 1 1 { /a10 exch def
-1 1 1 { /a11 exch def
xc yc translate
a11 1 add
a10 1 add 3 mul
add % a11, a10 X axis
xc mul % scale
a01 1 add
a00 1 add 3 mul
add % a10, a00 Y axis
yc mul % scale
translate
axes
paren
a00 0 0 matr
a01 0 1 matr
a10 1 0 matr
a11 1 1 matr
% uncomment this to use PostScript CTM
%[ a00 a10 a01 a11 0 0 ] concat
%block
%
% comment this to use PostScript CTM
blockh
%
grestore
} for
} for
} for
} for
quit