# Metapost: draw in relative coordination

In Metapost, we draw in this way:

    draw--(0,0)--(1,0)--(1,1)


and all the coordinations are based on the origin (0,0). Can we draw in a relative coordination system? For example, after drawing the part (0,0)--(1,0), the third point is (0,1) relative to the second point (1, 0), how can we draw in this way @(1,0)--(0,1)? @ means relative to. It is painful to define all points based on the same origin.

numeric u;
u := 1;
depth := 612u;
width := 229u;
tf := 19.6u;
tw := 11.9u;
r := 14u;

b := (width - tw) / 2;
hw := depth - 2 * tf;

beginfig(1)
pair p[];

p1 := (0, 0);
p2 := (width, 0);
p3 := (width, tf);
p4 := ((b + tw), tf);
p5 := ((b + tw), (hw + tf));
p6 := (width, (hw + tf));
p7 := (width, (hw + 2 * tf));
p8 := (0, (hw + 2 * tf));
p9 := (0, (hw + tf));
p10 := (b, (hw + tf));
p11 := (b, tf);
p12 := (0, tf);

draw p1--p2--p3--p4--p5--p6--p7--p8--p9--p10--p11--p12--cycle;
endfig


The figure is EDIT 2: Define points in relative coordination. As Thruston said, more efficient method should be available, but I don't know it so far.

Followed is Metapost code.

outputtemplate := "%j-%c.mps";
prologues := 1;

numeric u;
u := 0.1mm; % scale: 1:10

% section
depth := 612u;
width := 229u;
tf := 19.6u;
tw := 11.9u;
r := 14u;

% some calculation
b := (width - tw) / 2;
hw := depth - 2 * tf;

% relative coordination
def draw_WB_section (expr base) =
save p;
pair p[];

p1 := base;
p2 := p1 + (width, 0);
p3 := p2 + (0, tf);
p4 := p3 - (b, 0);
p5 := p4 + (0, hw);
p6 := p5 + (b, 0);
p7 := p6 + (0, tf);
p8 := p7 - (width, 0);
p9 := p8 - (0, tf);
p10 := p9 + (b, 0);
p11 := p10 - (0, hw);
p12 := p11 - (b, 0);

draw p1--p2--p3--p4--p5--p6--p7--p8--p9--p10--p11--p12--cycle;
enddef;

beginfig(1)
pair p[];

% absolute coordination
p1 := (0, 0);
p2 := (width, 0);
p3 := (width, tf);
p4 := ((b + tw), tf);
p5 := ((b + tw), (hw + tf));
p6 := (width, (hw + tf));
p7 := (width, (hw + 2 * tf));
p8 := (0, (hw + 2 * tf));
p9 := (0, (hw + tf));
p10 := (b, (hw + tf));
p11 := (b, tf);
p12 := (0, tf);

draw p1--p2--p3--p4--p5--p6--p7--p8--p9--p10--p11--p12--cycle;
draw_WB_section ((70,-10));
endfig


Followed is Latex code.

\documentclass[a4paper]{article}
\usepackage{graphics}
\begin{document}
\includegraphics{WB-1.mps}
\end{document}


Followed is compilation.

mpost WB.mp
pdflatex WB.tex


Followed is the PDF output. • Please provide compilable code. Are you looking for tranformations? – cfr Aug 12 '17 at 2:30
• @cfr the code is added. All the points are based on (0,0). For the point p2 and the following, it is better to use relative coordination based on the point defined just before it, e.g., p2 relative to p1, p3 relative to p2 and so on. – warem Aug 12 '17 at 10:38
• I think "better" is a matter of opinion, so you might not get very helpful answers here. From your code I'd suggest that you investigate exactly how declarative programming works in Metafont/Metapost. There are much more efficient ways to specify your shape using the z* notation and multiple equivalences. Having said that it would be possible to create a new macro using @ as you suggest that kept track of a current point, but I'm not sure that it would make the example that you have posted any clearer. – Thruston Aug 12 '17 at 21:05
• @Thruston You are right. "better or not" is just personal point of view. Someone thinks so, but others might not. I just came into Metapost a couple of hours and didn't know other weapons in Metapost. Could you please give a clue about z* notation? I couldn't find it in the manual mpman or maybe I misunderstood some. Thank you. – warem Aug 12 '17 at 21:34

So here is how I would code this diagram:

\RequirePackage{luatex85}
\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);
numeric w, h, tf, tw;
w = 22.9mm; h = 61.2mm; tf = 1.96mm; tw = 1.19mm;

x0 = x7 = x8 = x11 = 0;
x1 = x2 = x5 = x6 = w;
x3 = x4 = 1/2(w+tw);
x9 = x10 = 1/2(w-tw);

y0 = y1 = 0;
y2 = y3 = y10 = y11 = tf;
y4 = y5 = y8 = y9 = h - tf;
y6 = y7 = h;

path section;
section = for i=0 upto 11: z[i] -- endfor cycle;

path A, B;
A = section rotated 30;
B = section shifted (30mm,-10mm);

fill A withcolor 3/4[red,white]; draw A;
fill B withcolor 3/4[blue,white]; draw B;

endfig;
\end{mplibcode}
\end{document}


which produces this: ## Notes

1. I've wrapped this up in a luamplib wrapper, so you need to compile this example with lualatex, and it will produce a PDF in one step. You don't have to use this workflow; you could simply copy from the beginfig(1) to the endfig into your existing MP template and use your existing workflow. But I recommend that you do use the luamplib interface. You get exactly the same MP engine, but the font handling is so much simpler. Having said that the documentation is still lacking and debugging is harder, so please choose whichever workflow suits you best.

2. I've declared the variables as numeric - you don't have to do this, because an undeclared variable is implicitly numeric but I prefer to declare them and ensure that they have no existing value at the start of my figure.

3. I've used the mm unit directly instead of created my own unit with the u convention. Just another way of using MP.

4. I've then declared all the points as separate xs and ys. By convention (well actually by a macro defined in plain Metapost), if you have a point z0 you can refer to the x-part as x0 and the y-part as y0 etc, and in particular you can assign x0 and y0 separately if that's convenient.

5. To make the section shape I've used an inline for loop, but you could obviously write it out as section = z0--z1--z2--... etc. The only thing to note here is that inside the loop you have to put the suffix in brackets so that it gets parsed correctly.

6. Once you have defined the section as a path you can copy it, rotate it, shift it etc as shown. This is why you don't need "relative" path construction macros.. (in my opinion).

Hope that helps.

• Thanks Truston for the code. Personally, I perfer to relative coordination (not all ) because, in real detailing, other shapes are relative to one point by physical meaning. You can define them to the same origin but relatively defining will keep you clearer. Anyway, it is just personal point of view. – warem Aug 13 '17 at 20:08