[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