Robitex's Blog

Ideas in the web

Archivi Mensili: novembre 2009

Il fiocco di Von Koch in METAPOST


La curva di Von Koch

Il bellissimo fiocco di neve di Niels Fabian Helge von Koch, matematico svedese vissuto a cavallo del 1900, è una delle prime strutture frattali mai descritte.

Naturalmente è utile consultare la pagina web sull’argomento su wikipedia e quella dedicata da Wolfram MathWorld, ma certo non sarà difficile reperire in rete altre notizie se ancora non bastasse.

Si tratta di una curva chiusa di perimetro infinito ma di area finita, molto nota. Potevamo perdere l’occasione di generarla in METAPOST?

Effettivamente la curva si può costruire con il pacchetto METAOBJ, ma come problema ricorsivo non è male da implementare con quello che sappiamo già dai precedenti post.

La costruzione

Per ciascun lato di un triangolo equilatero si trovano i due punti che lo dividono in tre parti uguali, poi si costruisce il triangolo equilatero il cui lato è il segmento centrale che poi si elimina, e si reitera all’infinito su tutti i nuovi segmenti.

Building the Von Koch's curve

Building the Von Koch's curve

Come si vede dalla figura qui sopra il procedimento è semplice, ed avremo potuto introdurlo su un solo segmento. Si vedono le curve di Von Koch di livello 0, 1 e 2, con rispettivamente 3, 12, e 48 segmenti distinti.

METAPOST in action

Diciamo che nella variabile numerica lato memorizziamo la lunghezza del lato del triangolo di base che darà origine alla curva di Von Koch snowflake. Il codice per disegnare l’iterazione successiva deve trovare i due punti intermedi sul lato e costruire il triangolo equilatero sul terzo medio. Ecco il codice METAPOST:

beginfig(1);
numeric lato;
lato := 100;

pair a,b,p,q,r;

a := origin;
b := (lato,0);
p := 1/3[a,b];
q := 1/3[b,a];
r := q rotatedabout(p,-60);

draw a--p--r--q--b
withcolor .625red;
endfig;
end

Abbiamo fatto uso della comoda notazione per ricavare i punti P e Q che tripartiscono il segmento AB disteso sull’asse x e di lunghezza lato, e l’altrettanto comoda funzione rotatedabout() non nativa ma costruita con trasformazioni elementari, con la quale si crea il punto R, vertice del triangolo di prima iterazione.

Non rimane che costruire la funzione ricorsiva.
Faremo così: accetteremo in input i punti estremi del segmento ed il livello fino a cui la funzione disegnarà la curva di Koch, e su questo baseremo il controllo di terminazione della ricorsione:

se il livello richiesto è zero, allora disegna il segmento AB, altrimenti trova i punti intermedi P, Q ed R e lancia la funzione stessa sui quattro sotto lati AP, PR, RQ e QB.

Invece di elaborare oggetti path lavoriamo così più semplicemente sui punti vertice della curva. Lo stack delle chiamate ricorsive ci darà gratis l’ordine di disegno tra i punti fino al livello desiderato.

Il numero dei segmenti disegnati n è una funzione esponziale del livello v, si ha infatti (per il numero dei segmenti della la curva di Kock completa moltiplicare ulteriormente per 3):

\displaystyle n = 4^v

Ecco il codice completo:

beginfig(1);
pickup pencircle scaled .75pt;

vardef koch(expr aa,zz,level)=
save p,q,r;
pair p,q,r;

if level=0:
draw aa -- zz
withcolor .625red;
else:
p := 1/3[aa,zz];
q := 1/3[zz,aa];
r := q rotatedabout(p,-60);

koch(aa, p,level-1);
koch( p, r,level-1);
koch( r, q,level-1);
koch( q,zz,level-1);
fi
enddef;

numeric lato ;
numeric n;

lato := 420pt;
n := 5;
koch( origin   , (lato,0)     , n);
koch( (lato,0) , lato*dir(60) , n);
koch( lato*dir(60) , origin  , n);

endfig;
end

dove abbiamo utilizzato una macro vardef dando istruzione di utilizzo di p, q, ed r come variabili locali (comando save).

Pronti a scaricare il risultato nel formato PDF? Fate click allora sull’immagine sottostante.

A Von Koch flake with level 5

A Von Koch flake with level 5

Alla prossima.

Annunci

Dalla Pretesting alla TeX Live 2009


Ciao a te,
con l’arrivo della versione ufficiale della TeX Live 2009, l’11 novembre scorso, la versione Pretesting resa pubblica a scopi di test e feedback, ha perso i suoi repository.

Gli utenti che hanno installato la TeX Live Pretesting cosa devono fare?
La risposta è moooolto semplice e non è installare tutto da zero, ma basta rilocalizzare il repository!.

Dalla TeX Live Pretesting alla 2009 senza passare dal VIA!

Dunque, intanto sistemate sul Desktop in modo che stia comoda, una finestra di console (che abbiate a che fare con l’Explorer di Windows o con il DE di Linux è la stessa cosa).
Possibilmente sorseggiando un buon te, selezionate il mirror CTAN di cui vi fidate per esempio ftp.snt.utwente.nl con il comando (servono i diritti di root):

tlmgr option repository ftp://ftp.snt.utwente.nl/pub/software/tex/systems/texlive/tlnet

From TeX Live Pretesting to TeX Live 2009

From TeX Live Pretesting to TeX Live 2009, tlmgr command

Benvenuti nella TeX Live 2009!!!

Il triangolo di Sierpiński con METAPOST


La ricorsione è sempre la via migliore?

A not recursive algorithm for the Sierpinski fractal triangle

A not recursive algorithm for the Sierpinski fractal triangle

Sembra che il miglior modo di affrontare una struttura ricorsiva come il triangolo del matematico polacco sia appunto un algoritmo ricorsivo.

Tuttavia leggendo il codice relativo nel post predecente ho cominciato a ragionare sulla possibilità di chiamare ricorsivamente la funzione di disegno nominata sierpinski() una sola volta anziché tre volte, una per ciascun triangolo del livello inferiore.

L’idea che mi è venuta è quella di disegnare il triangolo dal basso, triplicando per ciascun livello successivo il disegno. Tuttavia questo si può elegantemente fare con un ciclo iterativo semplice!

Dunque vi propongo una seconda soluzione (scritta in METAPOST) in cui il disegno è ottenuto con un normalissimo ciclo for.

Il codice spiegato passo passo

Come d’abitudine propongo l’implementazione dell’idea sviluppandola di pari passo con il codice, seguito dal disegno che ne deriva.

Per prima cosa disegniamo il primo triangolo equilatero (per una breve e mirata introduzione a METAPOST potete far riferimento utile al post precedente su questo stesso blog).

beginfig(1);

u = 40 mm;
fill origin -- (u,0) -- u * dir(60)-- cycle
withcolor .625red;
drawarrow origin -- u * dir(60)
withpen pencircle scaled 5 pt;
endfig;
end

An example with the dir() METAPOST function

An example with the dir() METAPOST function

Impostare una variabile unità qui settata a 40 mm è molto comodo, ma quello che dovreste notare di questo codice è l’uso della funzione dir() per fornire al path le coordinate del vertice alto del triangolo equilatero. La funzione restituisce un vettore unitario che forma l’angolo specificato con l’asse x di senso antiorario con centro nell’origine.
Questo vettore viene visualizzato con il comando drawarrow seguente.

METAPOST disegna il vettore restituito da dir() come un punto corrispondente al secondo estremo dello stesso. Del resto sarebbe scomodo se nel path andasse il vettore piuttosto che il punto.

Nel prossimo esempio possiamo vedere l’uso del costrutto for impiegando la funzione dir() a riprova che dir(angolo) produce il disegno di un punto:

beginfig(2);
numeric u;
u = 40 mm;

for ang = 0 step 15 until 345:
draw u * dir(ang)
withpen pencircle scaled 12 pt;
endfor;
endfig;

A polar example with dir() METAPOST function

A polar example with dir() METAPOST function

Per andare avanti sul nostro obbiettivo Sierpinski, occorre spiegare il concetto di picture. I comandi grafici non fanno altro che plottare disegni in una picture. Ci sono sempre disponibili due oggetti picture, quella corrente detta currentpicture e quella vuota detta nullpicture. Un po’ di codice chiarirà di cosa si tratta:

beginfig(3);
% set the thin of the pen
pickup pencircle scaled 3pt;

draw fullcircle scaled 80pt
withcolor 0.5 green;

picture pic;
pic := currentpicture;
currentpicture := nullpicture;

draw pic;
draw pic shifted (80pt,0);
endfig;

The METAPOST picture concept at work

The METAPOST picture concept at work

All’oggetto pic di tipo picture viene assegnato il disegno corrente, che in quel momento contiene un cerchio verde, poi il disegno viene cancellato. In questo momento il cerchio verde si trova memorizzato in un solo luogo: la picture pic.
Allora possiamo tornare a riempire currentpicture disegnando prima pic nella sua posizione e poi in quella traslata a destra.

L’idea iterativa Sierpinski

% set the unit size
u = 10 mm;

% a picture object
picture sier;

sier:= currentpicture;
draw sier shifted (u,0);
draw sier shifted (dir(60) scaled u);

The basic idea for a iterative Sierpinski drawing method

The basic idea for a iterative Sierpinski drawing method

Questo frammento di codice è il cuore del programma che disegna il triangolo frattale in maniera iterativa e non ricorsiva.
Si presuppone che la currentpicture contenga all’inizio il triangolino di base molto piccolo. Dapprima si memorizza il disegno corrente nella variabile sier, di tipo picture naturalmente, e semplicemente l’aggiungiamo al disegno corrente stesso prima a destra e poi in alto a 60° al posto giusto.

In altre parole come si vede in figura, il triangolo rosso viene memorizzato in una picture e poi viene riaggiunto due volte nella posizione dei triangoli blu. Basterà iterare all’infinito questo procedimento!

Il ciclo for Sierpinski

beginfig(4);
% set the unit size
u = 0.65 mm;

% draw the basic smallest triangle
fill origin--(u,0)-- dir(60) scaled u --cycle
withcolor .625red;

% a picture object
picture sier;

% recursive level
level = 8;

% main drawing cycle
for i=0 upto level-1:
tmp := u * (2**i);
sier:= currentpicture;
draw sier shifted (tmp,0);
draw sier shifted (dir(60) scaled tmp);
endfor;

endfig;

Adesso il codice è completo. L’operazione precedente di copia a destra ed a 60° è inserita nel ciclo iterativo for che produce il triangolo del livello desiderato (ho scelto il livello 8).
Aggiungo che ad un dato livello i la copia del disegno deve esser fatta ad una distanza di u \cdot 2^i, poichè ogni volta che si sale di un livello, il lato del triangolo raddoppia (il doppio asterisco significa quindi elevamento a potenza).

Alla prossima!

Introduzione a METAPOST


METAPOST

Il linguaggio METAPOST possiede alcune caratteristiche peculiari come la possibilità di risolvere sistemi di equazioni lineari, ma la cosa che mi ha convinto a provare il babbo di Asymptote è stata la decisione degli sviluppatori di luatex di includerlo come libreria nativa con il nome di MPlib.

La sintassi di METAPOST sviluppato originariamente da John D. Hobby, è piuttosto asciutta, del resto deriva dal METAFONT l’originale programma di creazione di font tipografici dello stesso Donald Knuth, creatore di TeX, a differenza del quale produce un output Postscript (quindi il nome), digeribile anche da pdflatex (i disegni possono essere inseriti nel documento direttamente senza conversioni).

Naturalmente una qualsiasi distribuzione LaTeX (che sia TeX Live, MiKTeX o MacTeX), installarerà sul vostro sistema (che sia Linux, Windows o MacOS), la più recente versione di METAPOST.

Primo codice

La funzione primitiva per disegnare è chiamata (ovviamente) draw ed accetta come argomenti percorsi ed anche intere figure chiamate picture. Per esempio per disegnare un rettangolo 36×28 mm si scrive:

draw origin -- (36mm,0) -- (36mm,28mm) -- (0,28mm) -- cycle;

od anche (aggiungendo un po’ di colore):

u = 1mm;
draw origin -- (36u,0) -- (36u,28u) -- (0,28u) -- cycle
  withcolor .625red;

I punti del tipo pair vengono instanziati descrivendone le coordinate tra parentesi tonde ed equiparando l’idea di punto a vettore con il primo estremo nell’origine, così da poter effettuare trasformazioni geometriche come traslazioni (chiave shifted) oppure rotazioni (chiave rotated) od ancora operazioni di scala (chiavi scaled, xscaled, yscaled, zscaled).

Definiamo il rettangolo come percorso e disegnamolo due volte, la prima con riempimento grigio e la seconda solo con il contorno ma traslato del vettore (2mm,2mm), vediamo l’esempio (completando l’esempio con le istruzioni iniziali e finali indispensabili per la corretta compilazione):

% prima prova con METAPOST
beginfig(1);
u = 1.0mm;
path p;
p = origin -- (36u,0) -- (36u,28u) -- (0,28u) -- cycle;

fill p shifted (2u,2u) withcolor .75white;
draw p withcolor .625red;

endfig;
end

ed ecco il risultato:

First test of the METAPOST language

First test of the METAPOST language

Il parametro 1 passato alla funzione beginfig() non è altro che il numero che viene assegnato come estensione al file del disegno. Vengono infatti creati tanti file di output quanti ambienti beginfig()…endfig vi sono nel sorgente e quel numero serve appunto a numerarli.

Il codice va inserito in un file di testo con estensione .mp e poi compilato per ottenere i file dei disegni (il piccolo grande editor SciTE può essere di (grande) aiuto, come pure un visualizzatore Postscript).

Come vedete ci sono i punti e virgola finali che consentono di impaginare il sorgente come si desidera, i commenti che iniziano con il simbolo di percento, ed una sinteticità espressiva generale che in qualche modo esalta la potenza grafica di METAPOST (non lasciatevi ingannare dalla sua modestia…).

Esiste anche la possibilità di instanziare il vettore unitario con direzione specificata per mezzo della funzione dir() che accetta il valore dell’angolo con verso antiorario dall’asse x (così il punto dir(0) è del tutto equivalente al punto (1,0) ).

Per individuare un punto su un segmento è possibile utilizzare l’espressione factor[p1,p2], se factor = 0.50 verrà restituito il punto di mezzo.

Ecco l’ultimo esempio:

% seconda prova con METAPOST
beginfig(1);
% disegnamo un triangolo equilatero
u = 5 mm;

pair A; A=origin;
pair B; B=(7u,0);
pair C; C=(dir(60) scaled 7u);

pair m; m = 0.5[B,C];
pair g; g = 2/3[A,m];

path p; p = A--B--C--cycle;

% regolazione dello spessore della penna
pickup pencircle scaled 4pt;

draw p
     withcolor .625red;
fill p  scaled .8 shifted .2 g
     withcolor .565blue;

endfig;
end
More difficult METAPOST example

More difficult METAPOST example

Bene, ora ne sappiamo abbastanza per procedere, ma mi raccomando, la comprensione dei concetti qui esposti è molto superiore se eseguirete anche degli esercizi con METAPOST, pertanto fateli!!! Ne ricaverete ottime basi e grande soddisfazione.

Happy METAPOST!

Testare i server europei di CTAN


L’idea

Qualche tempo fa, durante i test della TeX Live 2009, la distribuzione TeX di imminente rilascio, proposi agli sviluppatori di dotare lo script tlmgr della possibilità di scaricare i file da più di un mirror CTAN allo stesso tempo per superare eventuali problemi con il server abituale (in quel momento il server ufficiale italiano era lentissimo).

L’idea venne rifiutata adducendo problemi tecnici, allora non ci rimane che ingegnarci per rispondere alla domanda qual’è il server mirror più veloce da settare come fonte di default per la nostra distribuzione?

netselect

L’utility netselect fa al caso nostro: prende in input una serie di url server e ne stila una classifica impietosa!!. Naturalmente il risultato non ha un valore assoluto poiché dipende dalla connessione che si sta utilizzando e dal traffico in quel momento presente, ecc.

CTAN test server

CTAN european server test result

Installiamolo in un attimo

Apriamo un terminale e digitiamo con i diritti di root:
apt-get install netselect

naturalmente stiamo parlando di un sistema Debian Like, per esempio Ubuntu.

Test sui server CTAN!

Copiate in un file il testo seguente, non è altro che il lancio di netselect su TUTTI i server europei di CTAN alla data di oggi (ci vuole un po’ di pazienza ma la faticaccia l’ho fatta io per voi 🙂 ), rendetegli i permessi di esecuzione e lanciatelo da terminale.

#!/bin/sh
netselect -vvv  ftp.univie.ac.at gd.tuwien.ac.at mirrors.dotsrc.org \
mirrors.dotsrc.org ftp.linux.ee ftp.funet.fi ctan.mines-albi.fr \
distrib-coffee.ipsl.jussieu.fr distrib-coffee.ipsl.jussieu.fr \
ftp.inria.fr ftp.oleane.net mirrors.ircam.fr  \
ftp.fernuni-hagen.de ftp.fu-berlin.de ftp.gwdg.de \
ftp.join.uni-muenster.de \
ftp.mpi-sb.mpg.de ftp.tu-chemnitz.de ftp.uni-erlangen.de \
sunsite.informatik.rwth-aachen.de ftp.cc.uoc.gr ftp.ntua.gr \
ftp.uoi.gr ftp.sztaki.hu ftp.heanet.ie \
ftp.heanet.ie ftp.uniRoma2.it ftp.fagskolen.gjovik.no \
ftp.fagskolen.gjovik.no ftp.gust.org.pl ftp.tpnet.pl \
mirror.icis.pcz.pl ftp.piotrkosoft.net \
piotrkosoft.net sunsite.icm.edu.pl ftp.di.uminho.pt \
ftp.eq.uc.pt ftp.ist.utl.pt neacm.fe.up.pt ftp.roedu.net \
ftp.chg.ru ftp.vsu.ru mirror.macomnet.net tex.ihep.su \
ftp.gui.uva.es ftp.rediris.es ftp.udc.es mirror.switch.ch \
ftp.cstug.cz ftp.cvut.cz ftp.ntg.nl www.cs.ruu.nl \
ftp.snt.utwente.nl anorien.csc.warwick.ac.uk \
anorien.csc.warwick.ac.uk mirror.ox.ac.uk

Chiamate il file contenente il comando con il nome di mirtest.sh e lanciatelo come root da terminale con l’istruzione: sudo ./mirtest.sh, ecco fatto.

Risultato

Anche in questo caso l’Italia non brilla, con un solo server ufficiale sito a Roma (punteggio 413), ma sarete senz’altro curiosi di conoscere il vincitore:

The winner is: ftp.snt.utwente.nl !!!

Il server ha ottenuto un punteggio di 165.
Fate anche voi la prova riportando qui un commento con il vostro vincitore.
Alla prossima! e buona gara.

Simmetria e spazio carta


Villette a schiera in AutoCAD

Ammettiamo che vi stiate occupando del disegno di una struttura simmetrica (semplice o multipla), come per esempio una villetta bifamigliare.

In teoria basta disegnare la metà dell’oggetto per definire tutto l’insieme, ma è necessario fornire disegni completi pertanto daremo un bel comando mirror per specchiare sull’asse di simmetria la parte opposta.

La soluzione va benissimo ma comporta un problema: in caso di modifiche occorre procedere di nuovo alla specchiatura, cosa che può essere piuttosto noiosa specie se sono richieste modifiche frequenti e se magari gli oggetti simmetrici si ripetono.

Nel nosto caso di riferimento, la pianta è composta da una parte sinistra ‘A’ ed una parte destra simmetrica ‘B’. Il disegno finale avrà schema AB. Se invece ci sono ripetizioni tipo ABABAB, allora gestire il disegno può diventare scomodo.

Soluzione spazio carta

Sappiamo come fare a risolvere con lo spazio carta quetso problema? Certo basta seguire questa semplice procedura che porterà il disegno nello spazio modello da così:

Model Space symetric object

Model Space symmetric object

a così nello spazio carta.

Final result in paper space

Final result in paper space

La procedura

Premessa: parleremo del caso con simmetria rispetto ad un asse parallelo ad Y con una versione 2004 di AutoCAD (segnalatemi eventuali problemi con le versioni più recenti).
Disegnamo nello spazio modello solamente la porzione A come per esempio quello della figura sopra e passiamo ad un layout dello spazio carta.
Creiamo una viewport che rappresenti nella scala voluta la parte A, e facciamone una copia accanto. Abbiamo adesso due viewport che rappresentano la stessa parte A.

Accediamo al menù Visualizza->Vista con nome… per attivare il dialogo corrispondente. Scegliamo come vista corrente “Basso” e premiamo il pulsante accanto “Imposta corrente”. Adesso diamo l’OK ed alla chiusura del dialogo selezioniamo la viewport di destra.

AutoCAD view dialog

AutoCAD view dialog

Non ci rimane che risettare i parametri della viewport specchio come scala ed inquadramento, e spostarla in modo da far corrispondere le due parti A e B.
Se volete potete cambiare colore al bordo della viewport per individuare meglio quella della parte destra da quella sinistra.

Difetti

Naturalmente una singola modifica nel modello si ripeterà allo stesso modo in tutte le altre porzioni del disegno che siano traslate o simmetriche alla porzione base.
Il risultato è ottimo, ma per la mia esperienza gestire in questo modo la simmetria comporta comunque degli svantaggi.

Il principale è senz’altro quello dovuto all’aumentata complessità dei layout, consiglio quindi di applicare il metodo comunque per un vostro disegno in modo che possiate valutarne l’efficienza.

Un secondo svantaggio è che non è possibile quotare in modo associativo nello spazio carta per i punti di quota appartenenti a diverse viewport, e quindi si perde il vantaggio eventuale di utilizzare un solo stile di quota per tutti gli oggetti dei layout (come vi segnalavo in questo post).

Dimenticavo…

Se l’asse di simmetria non è parallelo all’asse Y, potete sempre inserire il vostro disegno come un xrif ruotato in un altro, dove comporre i layout.
Scaricate pure il PDF di esempio, pesa solo 10 KB cliccando quì Drawing test in pdf format o sull’immagine seguente:

Pdf Example drawiong test

Pdf Example drawing test

Bye.

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