[metapost] reverse clip operation

Andreas Matthias andreas.matthias at tuwien.ac.at
Wed Sep 20 12:55:02 CEST 2006

Dan Luecking wrote:

> At 05:37 AM 9/19/2006, you wrote:
>> lfinsto1 at gwdg.de wrote:
>>>> Is it possible to reverse the clip operation? I.e. clip
>>>> everything that's /inside/ a clipping path and leave
>>>> the outside as is.
>>> Unless I'm misunderstanding you, it seems to me that unfilling the path
>>> would do the trick.
>> Yes, that's possible. But then everything within the clipping
>> path gets deleted (or actually filled with the background color),
>> which I would like to avoid.
> This was discussed before, I think. An eoclip operation would
> yield what you want (if MP had such a thing): provide two paths,
> one around the border of the figure and the one in question.
> Points in between the two will have a total winding number
> that is odd (1 for the border + 0 for the path = 1) while those
> inside the path will have a total of 2. An eoclip leaves only
> those with odd winding number (or only even depending on
> parameters).

Oh yes, now I remember that the terms are `nonzero winding number rule'
and `odd-even rule'.

> Here is an example:
> % The entire figure (path B) is filled with blue, then the part inside
> % a circle (path A) is removed _without_ filling it with white. Path C
> % is the clipping path. I have drawn this on a picture variable P to
> % prove that the circle is not filled: the line D is not covered
> % up inside B when P is drawn after it.
> beginfig(0);
>   picture P; path A,B,C,D;
>   A := fullcircle scaled 36 shifted (36,36);
>   B := (72,0)--(72,72)--(0,72)--(0,0)--cycle;
>   C := B         % around B
>        --(72,72) % and a quarter more.
>        --(reverse A)--cycle;
>   D := (0,0)--(72,72);
>   P := image( fill B withcolor blue; );
>   clip P to C;
>   draw D;
>   draw P;

But you are drawing D /before/ P. I would prefer to draw P /before/ D,
because the end point of D is calculated when drawing P.

> Trying to do it in pure MP is tough to get consistently right,
> but if one knows in advance what the path is, one can usually
> get the following to work: Define a path that goes all the way
> around the border of the figure and a little more (CCW), and
> then travels along a straight line to a point on the given path
> (but without passing into its interior) then around the path
> backwards (i.e. CW) and then back to the start (i.e --cycle) but
> making sure the line also doesn't go into the interior of the
> given path). Then use that path to clip.

I tried it but did not succeed. In the following example the
interior of `p' is again being filled by the clipping operation.


% a simple `picture'
path p;
p := (0,0) -- (1u,1u) -- (3u,1.5u) -- (4u,-2u) -- cycle;
fill p withcolor blue;

% the connection line to the `picture'
draw (4.5u,3u) -- (2.5u,0) withpen pencircle scaled 10bp; 

% now clipping the connection line
path clip_p;
clip_p := (-99u,-99u) -- (99u,-99u) -- (99u,99u) -- (-99u,99u) -- cycle
   -- p -- cycle;   
clip currentpicture to clip_p;



More information about the metapost mailing list