Robitex's Blog

Ideas in the web

Archivi Mensili: ottobre 2009

Il triangolo di Sierpiński


Il disegno della ricorsione

Visualizzare la ricorsione è l’idea di questo post. E la figura ricorsiva più semplice da disegnare mi sembra proprio il triangolo di Sierpiński. Dopo qualche notizia essenziale sul software che userò, passeremo al codice…

Sierpinski Triangle

Sierpinski Triangle of 6 level (click to download the pdf file)

Il linguaggio grafico di Asymptote

Per le nostre sperimentazioni useremo un software chiamato Asymptote, che consiste in un linguaggio di alto livello derivato dal METAPOST, piuttosto espressivo, simile a C++ e Java, quindi fortemente tipizzato.

Si possono instanziare i classici tipi numerici come int o real, e produrne di nuovi per mezzo del costrutto struct.

Infine, occorre terminare le istruzioni con il punto e virgola, utilizzare le parentesi graffe per definire i blocchi di codice, e produrre i commenti nel formato C++, ma vediamo subito un esempio (supporremo che una versione di Asymptote sia installata sul vostro sistema Windows, Linux o Mac OS che sia, magari tramite la TeX Live 2009).

Per disegnare una spezzata scrivete in un file di testo con estensione .asy il seguente codice, dove le coordinate sono separate da un doppio trattino che significa come in molti altri linguaggi del mondo LaTeX, una linea retta:

draw((0,0)--(2.5,2.5)--(5,0.5)--(7.5,5));

Poi in una finestra di console, date il comando di compilazione: asy -f pdf nomefile.asy. Al termine dell’elaborazione verrà rilasciato un file pdf contenente il risultato grafico desiderato.

Qualcosa di più complesso

Cominciamo a disegnare quello che sarà il triangolo di livello 0, utilizzando il tipo pair ovvero il tipo che in Asymptote corrisponde ad una coppia di numeri reali:

// triangle line length
real ell = 100;

// level 0 triangle:
pair p1 = (0,0);
pair p2 = (ell,0);
pair p3 = (ell/2,sqrt(3)*ell/2);
draw(p1--p2--p3--cycle);

Il termine cycle specifica che il percorso da disegnare sarà chiuso e corrisponde di fatto al primo punto p1.

Sierpiński

Il triangolo del matematico polacco venne da lui elaborato nel 1915, quando i sovietici tentavano di impossessarsi del cuore di quel popolo.

Disegnato un triangolo (che supporremo equilatero) detto di livello 0, si disegna il triangolo i cui vertici sono i punti di mezzo dei lati del triangolo principale, poi si applica ricorsivamente lo stesso procedimento ai tre sotto triangoli nord, sud-est e sud-ovest.

La struttura è un frattale in quanto è autosomigliante. Una semplice osservazione ci dice che man mano che si scende di livello le lunghezze dei lati dei triangoli si dimezzano, per cui se l_0 è la misura del lato del triangolo del livello 0, quella del lato a livello n sarà:

\displaystyle l_n = \frac{l_0}{2^n}.

Il numero dei triangoli t in funzione del livello v si ottiene considerando che scendendo di un livello il loro numero cresce di 3^v-1. In formule:

\displaystyle t = 1 + \sum_{i=1}^v 3^{i-1}

Per esempio al livello 5 i triangoli disegnati sono 122, ma al 10° salgono a 29.525 ed al 14° sono ben 2.391.485.

Il codice (non ottimizzato)

Per terminare i cicli ricorsivi altrimenti infiniti, è possibile utilizzare un criterio grafico: se lo spessore di tracciamento delle linee è tale che i triangoli dei livelli ulteriori risultano coperti, è inutile proseguire con il disegno.

La funzione ricorsiva chiamata sierpinski() prende i tre punti vertici del triangolo ed effettua immediatamente il test seguente (s è lo spessore del tratto ed l la lunghezza del lato del triangolo):

\displaystyle \frac{s}{2}\geq \frac{l}{2\sqrt{3}}

Se il test è falso significa che possiamo procedere al disegno del sotto-triangolo con i vertici nei punti di mezzo dei lati del triangolo principale, ed incrementare l’intero che conterrà alla fine il numero totale dei triangoli disegnati.

Il passo finale è lanciare ricorsivamente tre volte la funzione stessa sui sotto-triangoli del livello successivo.

Il codice non è ottimizzato perché in realtà non serve calcolare la distanza tra due punti per ottenere la lunghezza del lato del triangolo del livello attuale perché è ottenibile semplicemente dimezzando quella corrispondente al livello precedente.

Ecco il listato:

//
// Sierpinsky triangle: draw it with a recursive function
// Copyright (c) 2009 Roberto Giacomelli
// Term of licence see: https://robitex.wordpress.com/legalese/
//

// var setup
int n = 1;
real l0 = 100;
real s = 1.0;

// set the linewidth
defaultpen(s);

// main triangle
pair p1 = (0,0);
pair p2 = (l0,0);
pair p3 = (l0/2,sqrt(3)*l0/2);
draw(p1--p2--p3--cycle);

// function med() return the midpoint
// of the line ab
pair med(pair a, pair b){
return ((a.x+b.x)/2 , (a.y+b.y)/2);
}

// function dist() computes the length
// of line ab
real dist(pair a, pair b){
return sqrt((a.x-b.x)^2+(a.y-b.y)^2);
}

// main recursive function
void sierpinski(pair a, pair b, pair c){
// check graphic stop condition
if ( s<= dist(a,b)/sqrt(3) ){return;}

// draw subtriangle of the level
pair am = med(b,c);
pair bm = med(a,c);
pair cm = med(a,b);
draw(am--bm--cm--cycle);
++n;

//well, and now recursive running
// sublevel south east triangle
sierpinski(a,cm,bm);
// sublevel south west triangle
sierpinski(cm,b,am);
// sublevel north triangle
sierpinski(c,bm,am);
}
// draw the Sierpinski figure
sierpinski(p1,p2,p3);

// write on console the number
// of drawed triangles
write(n);

Scarica l’esempio in pdf : Sierpinski Triangle Figure
Alla prossima!

Cucinare tabelle numeriche con verbatim


Impaginare lunghissime tabelle numeriche? Impossibile, ma…

Alcuni programmi forniscono in output un file in formato rtf, contenenti lunghissime tabelle numeriche che arrivano a centinaia di pagine. La soluzione più semplice per stampare questo particolare tipo di documento è elaborarlo con MS Word o Writer di OpenOffice.org.

Se tuttavia il numero delle pagine potesse essere fortemente ridotto con semplici accorgimenti d’impaginazione si incorrerebbe immediatamente in alcuni problemi nel metterli in pratica.

Per loro natura i word processor devono visualizzare a schermo il risultato dell’impaginazione quindi se devono occuparsi d’impaginare all’istante un’enorme tabella numerica con layout a più colonne per pagina, magari anche diverso per le pagine dispari e per quelle pari, cadono rendendo di fatto impossibile perseguire il proprio obiettivo.

E qui che LaTeX entra in scena, essendo appunto un compositore di testi asincrono, basta copiare l’enorme tabella in un foglio di calcolo, aggiungere una colonna con i due \\ di fine riga, esportare il tutto nel formato CSV con il carattere & come simbolo di separazione tra i campi, ed aggiungere i comandi LaTeX necessari in un veloce file di testo che darà il file pdf finale.

Ma, vi voglio descrivere una seconda procedura che ho messo a punto or ora: si tratta di esportare la tabella come se fosse testo normale, con l’incolonnamento reso da caratteri spazio che compensano la diversa lunghezza del testo nelle celle, per poi comporre il tutto con un font monospaziato tramite l’ambiente verbatim.

La procedura è più semplice della precedente, anche se si perde la possibilità automatica di ripetere la prima riga di descrizione ad ogni cambio di colonna.

Occorrente

Procedimento

Rilassatevi un po’, magari al pensiero di un buon caffè che non avreste potuto gustare nella necessità di stampare ed impaginare un documento di 650 pagine fronte retro.

Dunque, nel quieto clima autunnale, aprite il file sorgente con la megatabella, in OpenOffice.org (oppure in Word), selezionate la tabella come sapete fare voi e copiatela negli appunti (CTRL+C).

Aprite anche una sessione di Calc, il foglio di calcolo di OpenOffice.org, e date un comando Incolla speciale… (CTRL+Maiusc+V), scegliendo l’opzione “Testo non formattato”.

Special Paste in OpenOffice.org Calc

Incolla speciale in OpenOffice.org Calc

Nel dialogo “Importazione testo…”, selezionate la prima colonna e, tenendo premuto il tasto Shift, selezionate anche l’ultima. In questo modo tutte le colonne saranno selezionate. Assegnatele il tipo Testo e date l’ok.

In questo modo si evita il problema del punto decimale che viene interpretato come separatore di un valore temporale (ore.minuti anziché parteintera.partedecimale), ma se la vostra tabella non comporta questo problema, fate pure direttamente il CTRL+V in Calc.

Import taxt dialog...

Il dialogo Importa testo

A questo punto salvate il file e subito dopo date un “Salva con nome…” per esportarlo in CSV (Comma Separated Values). Scegliete infatti tale formato nel dialogo e spuntate l’opzione “Modifica impostazioni filtro” che appare se appunto selezionate il formato di salvataggio CSV.

Save dialog

State per salvare un nuovo file...

Eventualmente, scegliete l’opzione “Mantiene il formato corrente” se Calc ve lo chiedesse in alternativa a “Salva in formato ODF”, premendo il corrispondente pulsante, e nell’ultimo dialogo attivate la miracolosa opzione “Ampiezza colonna fissa”

Last step

Ultimo passo per la creazione del file

Avete appena prodotto il file di testo giustamente incolonnato con caratteri spazio pronto per essere composto con LaTeX.

Se il risultato non fosse perfetto e di vostro gradimento, ritornate a Calc ed aggiustate la larghezza delle colonne per riesportate il tutto, infatti il testo monospaziato a tabella è ottenuto tenendo conto della larghezza delle colonne del foglio di calcolo, e questa è l’unica eventuale scocciaturina.

Il risultato aperto con l'editor Scite

Il risultato aperto con l'editor Scite

Ultimo passo: cottura della tabella

Aggiunto un \begin{verbatim} come prima riga del file testo esportato e un \end{verbatim} come ultima riga, scrivete in un sorgente .tex il codice seguente (be è solo un esempio…), ed a questo punto, mettete a cuocere il file a fuoco lento con pdflatex (lento si fa per dire naturalmente).

\documentclass[a4paper]{article}
% Seleziona un font monospaziato adatto
\usepackage{inconsolata}

% setta il margine di pagina
\usepackage[margin=10mm]{geometry}

% elimina testatine e piè di pagina
\pagestyle{empty}

\begin{document}
% riduzione dimensione del font
\footnotesize
% impaginazione standard su due colonne
\twocolumn

% inserisce il contenuto del file CSV
\input{carichi}
\end{document}

Vi troverete con il pdf finale pronto per essere servito (intanto ecco il pdf finale che ho ottenuto per illustrarvi i vari passaggi condito a dovere, scaricatelo è un esempio di 9,8 KB!).

Buon Appetito!

La tabellina pitagorica con PGF


Download articolo in PDF per la stampa

Motivazione

Recentemente un utente del forum del GuIT chiedeva lumi per la composizione in LaTeX di una tabella relativa alla tabellina pitagorica.

Ho provato a fornirgli una riposta fino a che i guru di TeX hanno risolto, ma mi rimaneva da realizzare un idea: disegnare la tabella con il pacchetto grafico PGF.

La tabellina pitagorica compilata in LaTeX con PGF

La tabellina pitagorica compilata in LaTeX con PGF

Disegno della griglia

Per disegnare la griglia della tabella pitagorica utilizziamo il comando \draw specificando un quadrato di 10 unità di lato (se non si specificano unità PGF intenderà centimetri), ecco il comando:

\draw (0,0) grid (10,10);

Riempimento della tabella

Per inserire i numeri nelle celle, risultato del prodotto tra il numero della colonna per quello della riga, basta scrivere due cicli \foreach; nidificati che eseguono il disegno di un nodo al cui centro è composto il testo del numero.

Abbiamo quindi due variabili \x ed \y. Al primo ciclo entrambe avranno valore 1 pertanto per individuare il centro del quadratino occorre dare molto comodamente l’opzione shift di (-0.5,-0.5) che applicate al punto (1,1) fornirà appunto le coordinate (0.5,0.50) ovvero il centro della prima casellina.

Ho copiato, questo si, il codice TeX per calcolare il risultato dell’espressione x * (11-y) che da il valore del prodotto in tabellina, poiché PGF risolve eventuali espressioni solo se si tratta di coordinate mentre per il testo da associare al nodo non effettua alcun parsing:

\foreach \x in {1,2,3,...,10}
\foreach \y in {1,2,3,...,10}
\draw[shift={(-.5,-.5)}] (\x ,\y) node 
                 {\number\numexpr\x*(11-\y)\relax};

Mettendo insieme il codice ecco il primo risultato che da la tabellina pitagorica con griglia di 1cm x 1cm:

% copiare ed incollare questo codice in un file
% testuale con estensione .tex, poi compilarlo con pdflatex
\documentclass[a4paper]{article}

\usepackage{tikz}
\pagestyle{empty}

\begin{document}

\begin{tikzpicture}
% grid definition
\draw (0,0) grid (10,10);

% fill numbers
\foreach \x in {1,2,3,...,10}
\foreach \y in {1,2,3,...,10}
\draw[shift={(-.5,-.5)}] (\x ,\y) node
                 {\number\numexpr\x*(11-\y)\relax};
\end{tikzpicture}

\end{document}

Completando e raffinando un po’ il codice, si ottiene il seguente listato, dove la cosa più importante è l’aggiunta dell’opzione scale all’ambiente tikzpicture che scala tutto tranne che il testo assegnato agli oggetti nodo, pertanto modificando un unico parametro si può regolare le dimensione della tabella.

% copiare ed incollare questo codice in un file
% testuale con estensione .tex, poi compilarlo con pdflatex
\documentclass[a4paper]{article}

\usepackage{tikz}
\pagestyle{empty}

\begin{document}

\begin{tikzpicture}[scale=0.675]
% grid definition
\draw (-1,0) grid (10,10);
\draw (0,10) grid (10,11);
\draw[line width=1pt, color=blue] (0,0) rectangle (10,10);

% fill numbers
\foreach \x in {1,2,3,...,10}
\foreach \y in {1,2,3,...,10}
\draw[shift={(-.5,-.5)}] (\x ,\y) node
                 {\number\numexpr\x*(11-\y)\relax};

% fill first row
\foreach \x in {1,2,3,...,10}
\draw[shift={(-.5,-.5)}] (\x , 11) node {\x};

% fill first column
\foreach \y in {1,2,3,...,10}
\draw[shift={(-.5,-.5)}] (0, 11-\y) node {\y};
\end{tikzpicture}

\end{document}

Il risultato è visibile nell’immagine iniziale, mentre per ottenere il risultato finale in formato PDF scontornato basta fare un click 😉 .

Alla prossima.

GuIT meeting 2009


Un convegno ancora più TeXnico

L’incontro annuale aperto a tutti del GuIT (Gruppo utilizzatori italiani di TeX) si è appena svolto nella solita cornice dell’Aula Magna della Scuola Sant’Anna a Pisa.

L’impressione che ne ho tratto è che quest’anno i contenuti sono stati ancora più tecnici, o meglio ancora più TeXnici per dirla con Donald Knuth. Mi ha colpito in particolare l’intervento di Luigi Scarso riguardante un estensione di LuaTeX chiamata lunatic, che permette di far girare codice Python all’interno di LuaTeX su una piattaforma Linux. Tecnologia piuttosto sofisticata che dimostra come il motore TeX stia entrando in una nuova fase specie quando arriverà LaTeX3 e la versione stabile di LuaTeX stessa (nella foto Luigi Scarso svolge la sua presentazione).

Parla Luigi Scarso

Parla Luigi Scarso

Naturalmente oltre agli argomenti specifici su LaTeX il meeting è un occasione assai piacevole per ritrovarsi, scherzare e scambiarsi opinioni con i guru del GuIT come il Prof. Enrico Gregorio e l’attivissimo Prof. Claudio Beccari. Nella foto seguente mi vedete accanto ad Agostino De Marco esperto utilizzatore delle tecnologie LaTeX relative alla grafica vettoriale nonchè relatore al convegno (grande ago).

Io ed Agostino De Marco

Io ed Agostino De Marco

Gli interventi in rete

La fondamentale foto di gruppo dei partecipanti con le altre immagini è già disponibile sul sito GuIT.

Tutti caduti nella rete invece gli interventi filmati da Kabeh Bazargan di River Valley Technologies con le sue diavolerie tecnologiche (il convegno è andato perfino in diretta streaming) e sono disponibili a questo link.

Gli articoli dei lavori presentati al meeting li trovate anche in ArsTeXnica n.8 la rivista semestrale del GuIT, naturalmente composta con LaTeX (per leggerla subito iscrivetevi al GuIT).

Per dirla in un unica frase “qualità elevata della conoscenza”.
O no…
Ciao.

L’area del triangolo dalle coordinate dei vertici


Scarica l’articolo in PDF per la stampa

L’area dalle coordinate?

A pensarci questo è un problema forse poco noto. L’area del triangolo può essere facilmente ottenuta calcolando le lunghezze dei lati a partire dalle coordinate dei vertici ed applicando la più famosa formula di Erone.
Ma è molto più semplice impiegare direttamente le coordinate…

Primo metodo

Il metodo utilizzato in questo post per determinare il baricentro del triangolo con il calcolo dei momenti statici consiste nel sommare il contributo con segno relativo a ciascun lato della figura considerando il trapezio che esso forma con l’asse cartesiano scelto.

Va bene, ma può essere utilizzato per determinare l’area del triangolo conoscendone le coordinate dei vertici?

Indichiamo i vertici con i numeri 1, 2, e 3, in questo modo sarà più semplice scrivere le coordinate dei vertici: 1 \equiv (x_1,y_1); 2\equiv (x_2,y_2); 3\equiv(x_3,y_3).

Dunque il trapezio sotteso al lato 12 ha area:

\displaystyle A_{12}=\frac{1}{2}(x_1 - x_2)(y_1 + y_2).

Sommando le aree dei trapezi relativi ai tre lati otterremo l’area del triangolo. Occorre percorrere i lati in senso orario così da ottenere i giusti segni per le aree dei trapezi.

L’espressione finale piuttosto simmetrica è dunque:

\displaystyle A= \frac{1}{2}(x_1y_2 - x_2y_1 + x_2 y_3 - x_3 y_2 + x_3y_1 - x_1y_3).

I sei termini della relazione dell’area ricordano i determinanti di matrici 2 x 2. Il primo termine infatti può esser visto anche come:

\displaystyle \begin{vmatrix}x_1&x_2\\ y_1&y_2\end{vmatrix}

così alla fine l’area la possiamo riscrivere anche nella forma facile da ricordare e compatta (che bellezza, è un vero portento di eleganza):

\displaystyle A=\frac{1}{2}\begin{vmatrix}1&1&1\\ x_1&x_2&x_3\\ y_1&y_2&y_3\end{vmatrix}.

Se non siete pratici con determinanti e matrici sappiate che non è difficile imparare le basi dell’algebra lineare.

Secondo metodo

Il problema si può anche trattare con i vettori, ricordando che la norma del prodotto vettoriale è l’area del parallelogrammo da essi formato. Infatti il prodotto dei vettori di \boldsymbol{u}\times \boldsymbol{v} ha norma pari a uv\sin{\alpha}, dove \alpha è l’angolo da essi formato.

Se consideriamo i due vettori che hanno in comune il primo estremo coincidente con un vertice del triangolo e come secondo estremo i rimanenti distinti vertici, sarà sufficiente calcolare la norma del loro prodotto vettoriale per poi dividerla per due.

In termini espliciti considerando il triangolo appartenente al piano xy (con questo metodo è possibile determinare l’area di un triangolo comunque posizionato nello spazio tridimensionale), sappiamo che il vettore \overrightarrow{12} ha componenti (x_2-x_1;y_2-y_1), che il vettore \overrightarrow{13} ha componenti (x_3-x_1;y_3-y_1), e che il prodotto vettoriale fra essi è il vettore dato dal determinante (che coincidenza, ancora un determinante):

\displaystyle \begin{vmatrix}\vec i&\vec j&\vec k \\ x_2-x_1&y_2-y_1&0\\ x_3-x_1&y_3-y_1&0\end{vmatrix}

che risolto fornisce direttamente la norma del prodotto poiché questo avrà una sola componente diretta come l’asse z che è:

\displaystyle (x_2-x_1)(y_3-y_1)-(y_2-y_1)(x_3-x_1)

che fornisce appunto la conferma alla formula precedente.

Notate come il determinate della formula compatta dell’area del triangolo si trasforma sommando le colonne immediatamente nell’espressione sovrastante.

La matematica non finisce mai di stupire non è vero…?
Ciao.

%d blogger hanno fatto clic su Mi Piace per questo: