5

Is it possible to draw dots with Metapost so that each dot is separated from its first neighbour by the same distance along an arbitrary path?

I do not want their real distance to be regular! Rather, I want their distance measured along the path to be equal.

I want to illustrate uniform curvilinear motion with that (and the uniformly varying one later).

For instance, I could want to put equally spaced dots along this line:

\documentclass[a4paper,10pt]{book}
\usepackage{luamplib}
\everymplib{input mpcolornames; beginfig(1);}
\everyendmplib{endfig;}
\begin{document}
    \begin{mplibcode}
      draw (0,0){right} .. (2cm,4cm){up} .. (4cm,5cm){right} .. (5cm,6cm){up} .. (8cm,7cm){right}
           withpen pencircle scaled 2pt;
    \end{mplibcode}
\end{document}
  • 1
    You want "arclength"... – Thruston Jan 18 '16 at 23:41
9

To follow this solution, you might like to look up "arclength" and "arctime" in the Metapost manual, or read my explanation below.

enter image description here

\documentclass{standalone}
\usepackage{luamplib}
\everymplib{beginfig(1);}
\everyendmplib{endfig;}
\begin{document}
    \begin{mplibcode}
        path P;
        P = (0,0){right} .. (2cm,4cm){up} .. (4cm,5cm){right} .. (5cm,6cm){up} .. (8cm,7cm){right};
        draw P withpen pencircle scaled 2pt withcolor .7 white;
        s = 5mm;
        for t=0 step s until arclength P: 
          drawdot point arctime t of P of P withpen pencircle scaled 4pt withcolor red; 
        endfor
    \end{mplibcode}
\end{document}

Notes

  • To work with a path it's helpful to save it as a variable. MP has several sorts of variables numeric, pair, path, string and so on. If you just assign to a variable, as s = 5mm;, MP assumes that it's numeric. So to save a path, you have to declare it first:

    path P;
    P = (0,0).....
    

    You can then draw it, or shift it about or rotate it etc.

  • You can also find out how long it is using length P. But MP has a rather curious notion of length, that Knuth christened time in the Metafont Book; the length of a path in MP time units is essentially the same as the number of points you used to define it, which is 5 in the current example. So you can do this:

    \begin{mplibcode}
    path P;
    P = (0,0){right} .. (2cm,4cm){up} .. (4cm,5cm){right} .. (5cm,6cm){up} .. (8cm,7cm){right};
    draw P withpen pencircle scaled 2pt withcolor .7 white;
    for t=0 upto length P: 
      drawdot point t of P withpen pencircle scaled 4pt withcolor red; 
    endfor
    \end{mplibcode}
    

    to produce

    enter image description here

    but as you can see the dots are not evenly spaced in this particular path, because they just appear at the five points used to specify it. You can have fractional time, so you could change the loop to

    for t=0 step 1/4 until length P: 
      drawdot point t of P withpen pencircle scaled 4pt withcolor red; 
    endfor
    

    and get:

    enter image description here

    but this just makes it more obvious that time is rather variable on a bendy path.

    However MP provides two more operators that give you absolute length instead of time.

    • arclength P returns the length of path P in PostScript points

    • arctime a of P returns the time t along path P where subpath (0,t) of P would have arclength equal to a. Got that?

    Using these facilities you can make the step value of your loop a real length, and use arctime to find the appropriate time along P. The only drawback of this is that the syntax becomes rather cumbersome. You don't need to add parentheses, but they might make it clearer:

    point (arctime t of P) of P
    

    This gets us to the diagram shown at the top with dots spaced every 5mm along P.

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.