[metapost] reverse clip operation

Dan Luecking luecking at uark.edu
Wed Sep 20 00:59:10 CEST 2006

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

B. Jackowski discussed a scheme for doing that in MP. There also
exist post-processing techniques (context's texexec, I think)
that can do it.

>I would prefer a reverse clipping operation. Would it be possible
>to write a macro, which does a reverse clipping?

Jackowski's method employed a trick: whenever text is placed in
the picture, MP puts something like

   (text) fontname 9.96265 fshow

in the output file. One uses the MP command "special" to
write a PS preamble that redefines (for the PS interpreter)
the fshow command and defines "fontname" to be the PS command
that MP lacks. (That's over-simplified, but is the basic idea).

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.

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.
  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;



Daniel H. Luecking
Department of Mathematical Sciences
University of Arkansas
"Be kind. Every person you meet is fighting a hard battle." - Anon.

More information about the metapost mailing list