Metapost cheatsheet

outputtemplate := "%c.svg";
outputformat   := "svg";

color grey ; grey:= (200/255,200/255,200/255) ;

set up outils

Placer des points

Alt text

beginfig(101);
    % Les points sont des couples de valeurs `x` et `y`. Dans Metapost, ils se nomment `z1`, `z2`, `z3`, etc.
    % le premier chiffre correspond à la valeur pour `x`, le deuxième à `y`.
    z1 = (0, 50);
    z2 = (100, 100);

    % Ici, nous définissons implicitement le point `z3`  en donnant les valeurs en `x` et en `y`.
    x3 := 200;
    y3 := 150;

    % La ligne suivante permet d'afficher nos trois points numérotés.
    dotlabels.top(1, 2, 3);
endfig;

Tracer des lignes

Alt text

beginfig(102);
    z1 = (0, 50);
    z2 = (100, 100);
    z3 = (200, 150);

    % La commande `draw` permet de dessiner des chemins.
    % Ici, on demande à metapost de tracer la ligne droite allant de `z1`à `z2`;
    draw z1--z2;

    % On peut choisir une couleur autre que le noir.
    draw z2--z3 withcolor blue;

    % La ligne suivante permet d'afficher nos trois points numérotés.
      dotlabels.top(1, 2, 3)
endfig;

Utiliser différentes plumes

Alt text

beginfig(103);
    z1 = (25, 25);
    z2 = (25, 50);
    z3 = (100, 75);

    z4 = (25, 75);
    z5 = (25, 100);
    z6 = (100, 125);

    z7 = (25, 125);
    z8 = (25, 150);
    z9 = (100, 175);

    % La commande `pickup` permet de choisir la plume de son choix.
    % La plume `pencircle` est celle par défaut.
    % Le mot clé `scaled` suivi d'une valeur permet d'en préciser l'épaisseur
    pickup pencircle scaled 4;
    draw z1--z2--z3;

    % La plume `pensquare` est simplement de forme carré
    pickup pensquare scaled 4;
    draw z4--z5--z6;

    % La plume `penrazor` n'a qu'une largeur et pas d'épaisseur. C'est une plume biseautée.
    pickup penrazor scaled 4;
    draw z7--z8--z9;
endfig;

Utiliser différentes terminaisons

voir Métapost raconté piétons, page 21.

Les terminaisons et jonctions des traits sont choisies par l’intermédiaire de deux variables pouvant prendre trois valeurs.

Pour la terminaison, la variable et ses trois valeurs % possibles sont : linecap:=butt; ou squared; ou rounded; (défaut)

Pour la jonction, la variable et ses trois valeurs possibles sont : linejoin:=beveled; ou mitered; ou rounded; (défaut).

Ici un exemple montrant montre un tracé avec des terminaisons en butt et une liaison en beveled :

Alt text

beginfig(104);
    z1 = (25, 25);
    z2 = (25, 50);
    z3 = (100, 75);

    linecap:=butt;
    linejoin:=beveled;

    draw z1--z2--z3 withpen pencircle scaled 9;
endfig;

Plume tournante?

cf. Gerrit Nordzij, The stroke

Alt text

beginfig(105);
    z1 = (0,0);
    z2 = (100,0);

    penpos1(10,90);
    penpos2(30,90);

    % Cette fonction s'appuie sur le penrazore dessing produit est un contour.
    penstroke z1e{up}..z2e..cycle;

    dotlabels.top(range 1 thru 2);
endfig;

Définir des unités et dessiner une grille basique pour rendre visible ces unités.

u:=20mm; % On définit ici l'unité de base. 20mm devient le pas de la grille.
width := 9u;
height:=6u;

fonction grille pour générer une grille def glyphe(suffix unicode, visible)= beginfig(unicode); if visible > 0: epaisseurgrille:=u/20; pickup pencircle scaled epaisseurgrille; boucle grille verticale for i=0 upto width/u: draw (iu, 0)--(iu, height) withcolor black; endfor boucle grille horizontale for i=0 upto height/u: draw (0, iu)--(width,iu) withcolor black; endfor enddef;

glyphe(106, 1);
endfig;

%![Fig. 107](figures/107.svg)

Définir des unités et dessiner une grille typographique

u:=20mm; % unité de base
chasse:=5u;
ascendante:=5u;
descendante:=2u;
hauteurx:=3u;
lignebase:=0u;

fonction grille pour générer une grille def glyphe(suffix unicode, visible, chasseunit)= 0 ou 1 comme premier argument pour rendre visble la grille et une valeur comme deuxième argument pour augmenter ou réduire la chasse en relation à l'unité de base beginfig(unicode); chasse:=chasseunitu; if visible > 0: epaisseurgrille:=u/40; pickup pencircle scaled epaisseurgrille; % boucle grille verticale for i=0 upto chasseunit: draw (iu, (ascendante+1u))--(iu, -(descendante+1u)) withcolor grey; endfor % boucle grille horizontale for i=(-descendante/u) upto ((0+ascendante)/u): draw (0, iu)--(chasse,i*u) withcolor grey; endfor

    pickup pencircle scaled (epaisseurgrille*2);
        % ligne de base
        draw (0,0)--(chasse,0) withcolor black;
        % ligne ascendante
        draw (0,ascendante)--(chasse,ascendante) withcolor .8grey;
        % ligne de hauteur d'x
        draw (0,hauteurx)--(chasse,hauteurx) withcolor .8grey;
        % ligne descendante
        draw (0,-descendante)--(chasse,-descendante) withcolor .8grey;
enddef;

glyphe(107, 1, 12);
    z1 = (25, 25);
    z2 = (25, 50);
    z3 = (100, 75);
endfig;

%![Fig. 107](figures/107.svg)

Se tailler sa propre plume

Attention faut pas que ça soit trop compliqué et il faut bien fermer le chemin avec cycle

Alt text

beginfig(108);
    % Il faut tout d'abord définir la forme de notre plume à l'aide d'un chemin.
    path p;
    p := dir(-30)--dir(90)--dir(210)--cycle;

    % On transforme ce chemin en plume.
    pen pentriangle;
    pentriangle := makepen(p);

    % On teste notre plume
    draw (0,0)--(20, 20) withpen pentriangle scaled 3;
endfig;

dessiner

Préciser la direction du tracé

Dessiner un A façon old script en utilisant des directions

Alt text

beginfig(202)
     z1 = (1u,0u);
     z2 = (4u,5u);
     z3 = (5u,0u);
     z4 = (1u,2u);
     z5 = (3u,1u);
     z6 = (6u,2u);

     draw z1--z2--z3{up}..z4..z5..z6;
endfig;

Dessiner une variante du T Lyno de Radim en utilisant des directions

Cf https://radimpesko.com/fonts/lyno

Alt text

beginfig(203);
    z1 = (2u, 2u);
    z2 = (2u, 4u);
    z3 = (1u, 4u);
    z4 = (3u, 4u);

    draw z1--z2{up}..z3{down}..{right}z4;

    % On numérote les points de 1 à 4
    dotlabels.top(range 1 thru 4);
endfig;

Être plus précis en spécifiant des angles

Alt text

beginfig(204);
    z1 = (2u, 2u);
    z2 = (2u, 4u);
    z3 = (1u, 4u);
    z4 = (3u, 4u);

    draw z1--z2{dir 110}...{dir 260}z3{dir 290}...{dir 20}z4;

    dotlabels.top(range 1 thru 4);
endfig;

S'y retrouver en dessinant un cadrant d'angles

Alt text

beginfig(205);
    z1 = (2u, 2u);
    z0 = (4u, 2u);
    z90 = (2u, 4u);
    z180 = (0u, 2u);
    z270 = (2u,0u);

    drawarrow z1--z0;

    dotlabels.top(0, 90, 180, 270);
endfig;

relier des points avec des courbes

Alt text

beginfig(206);
    z1 = (0, 50);
    z2 = (100, 100);
    z3 = (50, 0);

    draw z1..z2..z3;

    % On numérote les points de 1 à 3
    dotlabels.top(range 1 thru 3);
endfig;

Pour explorer les différents chemins possibles visiter aussi Metafont guide pratique de Bernard Desgraupes pages 34, 35

cycle

Un exemple Metapost classique: comment contraindre le chemin d'une courbe à l'aide de direction.

Alt text

beginfig(207);
    z1 = (0,0);
    z2 = (100,0);

    draw z1..z2..cycle;
    draw z1{up}..z2..cycle withcolor red;

    dotlabels.top(range 1 thru 2);
endfig;

scale D de Radim https://radimpesko.com/fonts/boymans

Alt text

beginfig(208);
    z1 = (1u, 1u);
    z2 = (1u, 6u);
    z3 = (2u, 6u);
    x4 = (3u);
    y4 = .5[y1,y2];
    z5 = (2u, 1u);
    path D;
    D := z1--z2--z3{dir 0}..z4..{dir 180}z5--cycle;
    draw D;
    draw D scaled 1.2 shifted (-0.4u, -0.5u);
        dotlabels.top(range 1 thru 5);
endfig;

Random

Alt text

beginfig(209);
endfig;

stocker

miroiter

Alt text

beginfig(301);
endfig;

dévier

Alt text

beginfig(302);
endfig;

Définir un chemin et un sous-chemin

Ici le tracé du C est basé sur celui d'un O qu'il ne reprend que partiellement.

Alt text

beginfig(303);
    z1=(3u, 5u);
    z2=(1u, 2.5u);
    z3=(3u, 0u);
    z4=(5u, 2.5u);

    path p;
    p := z1..z2..z3..z4..cycle;

    draw subpath(-0.5, 2.5) of p withpen penrazor scaled 9 withcolor blue;
    draw p dashed evenly;

    % pour plus de détails sur les pointillés voir *Métapost raconté aux piétons* page 22

    dotlabels.top(range 1 thru 4);
endfig;

image functions

Alt text

beginfig(304);
endfig;

repeat

Alt text

beginfig(305);
endfig;

Points relatifs et déduction de points

Trouver un point situé entre deux autres points

Alt text

beginfig(401);
    z1 = (0u,0u);
    z2 = (0u,5u);
    z3 = .5[z1,z2];  % z3 est le point à mi-distance de z1 et z2;

    draw z1..{left}z3..z2;

    dotlabels.top(range 1 thru 3);
endfig;

Variable de largeur

définir une variable qui va étendre (extanded) de la lettre, modifier les proportions

Alt text

beginfig(402);
endfig;

Whatever: trouver un point appartenant à une droite

Alt text

beginfig(403);
    chasse := 7u;
    hauteur := 5u;
    transversale := 2u;

    x1 = 0;
    x3 = chasse;
    x2 = .5[x1,x3];

    y1 = y3 = 0;
    y2 = hauteur;
    y4 = y5 = transversale;

    z4 = whatever[z1,z2];
    z5 = whatever[z2,z3];

    pickup pencircle scaled 5;

    draw z1 -- z2 -- z3;
    draw z4 -- z5;
endfig;

Points d'intersection

Alt text

beginfig(404);
        path p, pp;

        p := (0,100) -- (50,0) -- (100,100);
        pp := p shifted (25, 0);

        pair i;
        i = p intersectionpoint pp;

        pickup pencircle scaled 20;

        draw point 0 of p -- point 1 of p -- i -- point 1 of pp -- point 2 of pp;
endfig;