METAPOST syntax to set all values of an array at once
The array-like naming convention B[1]
, E[3]
is a MetaPost construction with so-called subscripts (in our case, 1
and 3
) rather than real arrays, which MetaPost doesn't handle with. But, as a macro language, you could define your own macro to automatically create pairs (please correct me if I'm using the wrong terminology):
vardef ListofPairs(suffix $)(text Pairs) =
save i_; i_ := 0; %save makes i_ local
pair $[]; %define a pair with the variable name $
%Typical loop over passed elements
for i = Pairs: $[i_] := i; i_ := i_ + 1; endfor;
enddef;
ListofPairs(B)((5,60),(5,-115),(10,180));
drawdot B[0] withpen pensquare scaled 12 withcolor red;
drawdot B[1] withpen pencircle scaled 10 withcolor green;
drawdot B[2] withpen pencircle scaled 8 withcolor blue;
As a friendly recommendation, don't expect MetaPost to be like "normal" programming languages. Instead, the MetaPost manual is a good starting point (texdoc metapost
if you have a complete distribution installed). The METAFONTBook is recommended too, but tbh I didn't read it so far.
This answer is really not much more than a comment on the other one, but the comment box is too small. There are a couple of useful built-in features and macros in plain.mp
that help with this sort of task in Metapost.
Consider the following little program:
vardef makePairs@#(text arguments) =
save i; numeric i; i = -1;
pair @#[];
for t = arguments:
@#[incr i] = t;
endfor;
enddef;
makePairs B ((0,1), (1, 2), (2, 3));
for i=0 upto 9:
if known B[i]: show i; show B[i]; fi
endfor
end
If you run this with mpost
you should get the following output
>> 0
>> (0,1)
>> 1
>> (1,2)
>> 2
>> (2,3)
Notes
I've avoided using the trailing
_
in my variable names, to avoid any possibility of overwriting something inplain.mp
, where_
is used in the names of internal variablesI have used the special suffix parameter notation
@#
instead of a delimitedsuffix
parameter. This allows for a slightly more "natural" syntax; the user can writemakePairs B ((0,1),....)
instead ofmakePairs(B)((0,1),...)
.After
save i
, I have redeclaredi
as numeric, so that any previous value is removed. This is just good practice.I have used the macro
incr
fromplain.mp
to increment the index instead of the clunkyi := i + 1
syntax.Finally I have used
known
to check whether a particular suffix is defined in my "array". In Metapost, variables with numeric suffixes are quite unlike arrays in other languages, despite appearances. So it is possible to defineB[0]
andB[2]
, without definingB[1]
and there is no way to check the "length" of suffixed variable.
Further simplification
And if you like the above, note that you can omit the parentheses from the final parameter, so we can make the syntax even less fussy for the user, like this:
vardef declarePairs@# text arguments =
save i; numeric i; i = -1;
pair @#[];
for t = arguments:
@#[incr i] = t;
endfor;
enddef;
declarePairs B (0,1), (1, 2), (2, 3);
for i=0 upto 9:
if known B[i]: show i; show B[i]; fi
endfor
end
And yet another idea
Depending on what you want to do with all the pairs in the "array", one other possibility is to create them all as a single path
:
path p;
p = (0,1) .. (1,2) .. (2,3);
then you can get at each pair with point 0 of p
, point 1 of p
, and so on. You don't actually have to draw the path, you could just use it as a sort-of list structure. And in this case MP does provide a length
command and you can reverse it with reversed
or do certain simple bits of arithmetic on the whole thing. For example p := p shifted up
would add 1 to the ypart
of each point in the path.