Robitex's Blog

Ideas in the web

Metapost: proiezione punto su retta


Potenzialità lineari di Metapost

La sintassi di Metapost è da considerare un po’ datata ed a volte puntigliosa?
Meglio usare programmi di disegno preferibilmente vettoriale?

Oppure possiamo parlare la lingua di Metapost ragionando tranquillamente di relazioni geometriche, semipiani e vettori…

Allora, Metapost parlando, ci proponiamo in questo post di disegnare il punto proiezione di uno dato su un segmento, alla maniera di John Hobby, il creatore originale di questo potente tool basato su Postscript, entrando nei dettagli tecnici.

Un punto qualsiasi

In Metapost per dire che ci stiamo riferendo ad un punto qualsiasi (od anche ad un valore qualsiasi, dipende dal contesto), si usa il termine whatever. Con le informazioni disponibili, Metapost tenterà comunque di individuare un punto esatto (a meno delle approssimazioni numeriche), permettendoci di esprimere facilmente vincoli geometrici.

È anche possibile utilizzare una mediation expression per trovare punti su un segmento. Si premette un numero ai punti tra parentesi quadre, così il punto di mezzo del segmento AB è 0.5[A,B].
Se controllate, abbiamo già fatto uso della mediation in altri post, come per esempio quello riguardante il fiocco di Von Koch, per suddividere il lato in tre parti uguali.

Un punto qualsiasi sulla retta passante per i punti A e B è un’affermazione che si esprime con whatever[A,B].

Rette ortogonali

Che significa in Metapost sottrarre due punti? L’operazione sottrae le coordinate così l’espressione B-A possiamo pensarla come il vettore AB esattamente come se utilizzassimo la notazione comune in Meccanica Razionale, ma con il primo estremo nell’origine.

L’operazione di rotazione di 90° della differenza tra due punti, fornirà quindi il vettore uscente dall’origine e di direzione ortogonale alla retta passante per i due punti. Un breve esempio chiarificatore:

outputtemplate:="ortoa.mps";

beginfig(1);
% draw axis
numeric dim;
dim := 200;
drawarrow origin -- (dim,0); % x
drawarrow origin -- (0,dim); % y

pair a,b;
a := ( 10,32);  % se non sono indicate unità viene
b := (180,80);  % assunto il bp (big point) di Postscript

drawoptions(withcolor red withpen pencircle scaled 2);
drawarrow a--b;
drawarrow origin -- (b-a) dashed evenly;
drawarrow origin -- (b-a) rotated 90 dashed evenly;

% labels
drawoptions(withcolor blue);
dotlabel.bot("A",a);
dotlabel.bot("B",b);

label.bot(btex $x$ etex,(dim,0));
label.lft(btex $y$ etex,(0,dim));
label.llft(btex $O$ etex,origin);
endfig;
end;
A Metapost example on vector subtraction and rotation

A Metapost example on vector subtraction and rotation

Proiezione ortogonale (potenza di Metapost)

Chiamiamo C il punto da proiettare e P il punto di proiezione sulla retta AB.
Allora, se si vuole che il vettore di proiezione CP sia proporzionale al vettore della retta di proiezione scriveremo:
p-c = whatever*(b-a) rotated 90;
Nell’espressione whatever assume il ruolo di un fattore per condizione geometrica di parallelismo dei vettori.

Aggiungiamo il secondo vincolo, ovvero che il punto P appartiene alla retta AB:
p = whatever[a,b];

Adesso Metapost è in grado di risolvere il sistema di equazioni per trovare il punto P.

Codice completo e compilabile

Ricordo che l’output Metapost è direttamente utilizzabile da pdfLaTeX, quindi è possibile includerlo in documento per ottenere il pdf. Ecco quindi il codice immediatamente compilabile, dove la distanza di P dalla retta viene calcolata con la distanza pitagorica implementata in Metapost con l’operatore ++, e stampata sul terminale con il comando show:

outputtemplate:="ortob.mps";

beginfig(1);
% draw axis
numeric dim;
dim := 200;
drawarrow origin -- (dim,0); % x
drawarrow origin -- (0,dim); % y

pair a,b,c,p;
a := ( 25,32);  % se non sono indicate unità viene
b := (180,80);  % assunto il bp (big point) di Postscript
c := (80,180);

p-c = whatever * (b-a) rotated 90;
p = whatever[a,b];

drawoptions(withcolor red withpen pencircle scaled 2);
draw a--b;
draw p--c dashed evenly;

% labels
labeloffset := 6;
drawoptions(withcolor blue);
dotlabel.bot("A",a);
dotlabel.bot("B",b);
dotlabel.top("C",c);
dotlabel.bot("P",p);

label.llft(btex $x$ etex,(dim,0));
label.llft(btex $y$ etex,(0,dim));
label.llft(btex $O$ etex,origin);

numeric dist;
dist := xpart (c - p) ++ ypart (c - p);
show dist;%   -> 125.10623 bp
endfig;
end;
Metapost figure on point projection

Metapost figure on point projection

Saluti e buona estate!

2 risposte a “Metapost: proiezione punto su retta

  1. Bit3Lux 21/07/2010 alle 16:12

    il tuo blog è stato aggiunto tra i miei preferiti; complimenti davvero!😀

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: