[metapost] Filling complex paths

Peter Rolf indiego at gmx.net
Fri Oct 17 19:29:23 CEST 2014


Am 17.10.2014 um 11:54 schrieb Tobias Columbus:
> On Fri, Oct 17, 2014 at 09:46:34AM +0200, Hans Hagen wrote:
>> On 10/17/2014 9:38 AM, Hans Hagen wrote:
>>> On 10/16/2014 11:44 PM, Tobias Columbus wrote:
>>>> Hi all,
>>>>
>>>> I am currently writing a piece of software that should spit out some
>>>> MetaPost
>>>> code. My input are the closed curves of a glyph and I want to produce
>>>> MetaPost
>>>> code that fills them according to Postscript rules. However, as
>>>> MetaPost cannot
>>>> handle non-contiguous closed paths, this task seems difficult at least.
>>>>
>>>> Note that the glyphs come from non-Postscript fonts, so that the MetaPost
>>>> "glyph" primitive does not work for me. I also tried "graphictext" as
>>>> described
>>>> in the Metafun manual but that turned out to be too inaccurate. I
>>>> traced the
>>>> inaccuracy back to "pstoedit", which is called for "graphictext".
>>>>
>>>> My attempt was to fiddle around with specials and
>>>> withprescript/withpostscript.  This attempt turned out to be nonsense as
>>>> addto always writes "stroke" or "fill" and my specials were ignored. I
>>>> could, of course, write the whole glyph with specials, but I would
>>>> prefer a cleaner solution.
>>>>
>>>> Has anybody some experience with this kind of problem? How difficult
>>>> would it be to add filling of non-contiguous paths to MetaPost?
>>>
>>> some of this unfilling is supported out of the box
>>>
>>> \startMPpage
>>>
>>> path p ; p := fullcircle scaled 10cm .. fullcircle scaled 5cm .. cycle ;
>>> fill p ; drawarrow p withcolor red ;
>>>
>>> currentpicture := currentpicture shifted (-11cm,0) ;
>>>
>>> path p ; p := fullcircle scaled 10cm .. reverse fullcircle scaled 5cm ..
>>> cycle ;
>>> fill p ; drawarrow p withcolor red ;
>>>
>>> \stopMPpage
>>
>> btw, with -- it's a bit less fun
>>
>> \startMPpage
>>
>> path p ; p := fullcircle scaled 10cm -- fullcircle scaled 5cm -- cycle ;
>> fill p ; drawarrow p withcolor red ;
>>
>> currentpicture := currentpicture shifted (-11cm,0) ;
>>
>> path p ; p := fullcircle scaled 10cm -- reverse fullcircle scaled 5cm --
>> cycle ;
>> fill p ; drawarrow p withcolor red ;
>>
>> \stopMPpage
>>
> 
> Hi Hans,
> 
> Thanks for your answer. I already tried something along the lines you suggest.
> However, the result contained lines intersecting the regions of the glyph that
> were supposed to be transparent. I thought about writing an algorithm that
> constructs a path to the "reverse inner shapes" that does not intersect the
> transparent regions. However, that seemed to be daunting and (perhaps) not worth
> the hassle. It may also be rather easy to construct such paths with Metapost,
> but I am rather new to Metapost...
> 
Hi Tobias,

donno if a manual path adaption is acceptable for you... it probably
depends on the number of used glyphs.

Anyhow, I wrote this small helper code a few days ago and my MP was
quite rusted (I mixed lua and MP syntax). Seems to work, but no guarantee.

\startMPinclusions
% shift a closed sub path p, so that it starts with point n
primarydef p cycleshifted n =
    if cycle(p) and (n<>0):
         (hide(numeric __b,__l; __l = length p; __b := n mod __l;)
         (subpath(__b,__l+__b) of p))
%         (subpath(__b,__l) of p .. subpath(1,__b-1) of p .. cycle))
    else: p fi
enddef ;
\stopMPinclusions


save p; path p[];
p1:= unitsquare xyscaled(w,h) wellrounded r; % HQ smoothed
p2:= reverse( fullcircle scaled 0.17w shifted(0.13w,0.13h) );
p3:= reverse( fullcircle scaled 0.8w shifted(0.5w,0.5h) );


fill p1 cycleshifted -1 -- p2 cycleshifted 11 -- p3 cycleshifted 12 --
cycle;


The linked example graphic (rotate*.pdf) uses exactly these values.

http://www.wuala.com/indiego/public/ConTeXt/


Sorry, no algorithm to solve this mess automatically.


Peter



More information about the metapost mailing list