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