2

I wrote a little Metapost macro that draws a smiley. I'd like to place another instance next to the first, maybe a little larger (size is a parameter). How can I place multiple separate instances?

Here's what I have so far:

prologues := 3;
outputtemplate := "%j-%c.png";
outputformat := "png";

def face(expr x) =
  begingroup
    u := 8bp;
    p := 3u;
    d := x*u;
    r := 0.3*d;
    pickup pencircle scaled p;
    fill fullcircle scaled d withcolor black;
    draw fullcircle scaled d withcolor white;
    drawdot (0,r) rotated -35 withcolor white;
    drawdot (0,r) rotated 35 withcolor white;
    draw (0,r) rotated 110 .. (0,r) rotated 180 ..
      (0,r) rotated -110 withcolor white;
  endgroup
enddef;

beginfig(1)
  face(50)
endfig;
end
6

You can wrap the other face into a temporary picture using image( ... ) and then shift and scale the whole thing.

You might also want to scale everything down a little bit altogether because your units are getting close to arithmetic overflow.

prologues := 3;
outputtemplate := "%j-%c.png";
outputformat := "png";

def face(expr x) =
  begingroup
    u := 8bp;
    p := 3u;
    d := x*u;
    r := 0.3*d;
    pickup pencircle scaled p;
    fill fullcircle scaled d withcolor black;
    draw fullcircle scaled d withcolor white;
    drawdot (0,r) rotated -35 withcolor white;
    drawdot (0,r) rotated 35 withcolor white;
    draw (0,r) rotated 110 .. (0,r) rotated 180 ..
      (0,r) rotated -110 withcolor white;
  endgroup
enddef;

beginfig(1)
  face(50);
  draw image( face(50); ) scaled (1.2) shifted (500bp,0) ;
endfig;
end

enter image description here

|improve this answer|||||
  • Thanks, the image() command is what I needed. But what is the value of maxdimen? I don't see it in mpman.pdf nor in the first couple pages of a google search. – dedded Nov 20 '19 at 4:31
  • @dedded Ugh, I don't actually know what it is called in MetaPost, but if you units are too large you get an error Arithmetic overflow. I'll check what the number is. – Henri Menke Nov 20 '19 at 5:18
  • @dedded It's 4096bp, see Section 6.1 in the MetaPost manual. – Henri Menke Nov 20 '19 at 5:28
  • You could also put the image into the macro, so that the macro just produced a picture which you could then draw or transform as you needed... – Thruston Nov 20 '19 at 8:24
  • @HenriMenke, Wow, 4096 is quite the limit in a age when 7680 × 4320 is a defined monitor standard (8K UHD). – dedded Nov 20 '19 at 13:12
3

Here is a version with the image operator in the macro...

enter image description here

prologues := 3;
outputtemplate := "%j-%c.png";
outputformat := "png";

vardef face(expr diameter) = image(
    save p; pair p; p = up scaled 0.3 diameter;
    fill fullcircle scaled diameter withcolor black;
    draw fullcircle scaled diameter withcolor white;
    drawdot p rotated -35 withcolor white;
    drawdot p rotated 35 withcolor white;
    draw p rotated  110 
      .. p rotated  180 
      .. p rotated -110 withcolor white;
    ) 
enddef;

beginfig(1)
    pickup pencircle scaled 20;
    draw face(400) rotated 20 shifted 200 left;
    pickup pencircle scaled 10;
    draw face(200) scaled 1.618 shifted 200 right;
endfig;
end

Notes

  • vardef is like def but automatically adds the begingroup and endgroup for you.

  • if you want the value of p restored at the endgroup you need to save p; at the beginning of the group.

  • it's good practice to explicitly define your local variables, rather than re-asssign them with :=

  • it's easier to define a pair here than to keep writing (0, r). Personally I find it easier to use up rather than remembering that (0, 1) means up...

  • you can apply any translation to the picture and you can pass it to draw or label to put it on the page

  • but don't try draw face(200) withcolor red; -- or rather do try it, and see that it's probably not a good idea.

  • You might also consider doing

    picture Smiler;
    Smiler = face(360);
    draw Smiler shifted 40 right;
    draw Smiler shifted 100 right rotated 90;
    % etc
    
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for?Browse other questions tagged or ask your own question.