1

Suppose I have some fairly trivial metapost code:

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

beginfig(1);
  pickup pencircle scaled .2in yscaled .2 rotated 30;    
  u := 36;

  z0 = (0,0);
  z1 = (0,1u);
  z2 = (1u,0);
  z3 = (0,-1u);
  z4 = (-1u,0);

  draw z1 -- z3 withcolor .7white;
  draw z2 -- z4 withcolor .7white;

  dotlabels.top(0,1,2,3,4);

endfig;    
end

This outputs a cross figure which intersects at the origin, z0.

Just as an illustrative example, suppose I would like the intersection between the two strokes to be smoothed: I would need the points of intersection between the two strokes, and then points along the paths, like so:

enter image description here

The red dots being the points of intersection, and the blue dots points along the path of the pen strokes.

It seems to me that if it were possible to acquire the path of the pen strokes, it would be very easy to accomplish what I have in mind.

  • makepath p gives you a path that corresponds to the outline of the pen p. You can work out the path of the strokes once you know that.... – Thruston Jan 31 '18 at 21:20
  • @Thruston I know about makepath but I'm a little bit confused about this would work in practice. What about a pen which rotates via penpos? – Kevin Keith Jan 31 '18 at 21:23
  • The penpos and penstroke macros are completely different from regular pens. – Thruston Jan 31 '18 at 22:18
  • 1
    the new envelope operator does this... – Thruston Apr 12 '18 at 9:44
  • 2
    envelope nib of stroke gives you a path that is the outline of path stroke drawn with pen nib.... – Thruston Apr 12 '18 at 9:45
1

Here is an example of how to use the new envelope operator.

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

beginfig(1);

    % pickup pencircle scaled .2in yscaled .2 rotated 30;    

    % this only works with a polygonal pen, so lets make a close approximation to pencircle...
    pen knib;
    knib = makepen((for t=0 upto 30: right scaled 7.2 rotated 12t -- endfor cycle) yscaled 1/5 rotated 30);
    pickup knib;

    u := 36;

    z0 = (0,0);
    z1 = (0,1u);
    z2 = (1u,0);
    z3 = (0,-1u);
    z4 = (-1u,0);

    draw z1 -- z3 withcolor .7white;
    draw z2 -- z4 withcolor .7white;

    % switch back to the default pen
    pickup defaultpen;
    draw envelope knib of (z1--z3) withcolor red;
    draw envelope knib of (z2--z4) withcolor blue;

    dotlabels.top(0,1,2,3,4);

endfig;
end.

this produces this (with clipping and fonts courtesy of imagemagick...):

enter image description here

which is more or less what the OP wanted.

The next stages would be to save the paths returned by envelope as path variables and use intersectionpoint to find the points where they cross. You may need to make judicious use of subpath to get the exact crossing point you want.

I'm using MP 2.000

toby$  mpost --v
MetaPost 2.000 (TeX Live 2017) (kpathsea version 6.2.3)
The MetaPost source code in the public domain.
MetaPost also uses code available under the
GNU Lesser General Public License (version 3 or later);
therefore MetaPost executables are covered by the LGPL.
There is NO warranty.
For more information about these matters, see the file
COPYING.LESSER or <http://gnu.org/licenses/lgpl.html>.
Original author of MetaPost: John Hobby.
Author of the CWEB MetaPost: Taco Hoekwater.
Current maintainer of MetaPost: Luigi Scarso.

Compiled with cairo 1.14.8; using 1.14.8
Compiled with pixman 0.34.0; using 0.34.0
Compiled with libpng 1.6.29; using 1.6.29
Compiled with zlib 1.2.11; using 1.2.11
Compiled with mpfr 3.1.5; using 3.1.5
Compiled with gmp 6.1.2; using 6.1.2

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.