8

I have three circles A, B, C whose centers are collinear and equally spaced. I would like to clip the region which is inside the middle circle, but outside the other two. I do a poor man's version of this by clipping the inside circle and simply filling the inside of the other two circles with white. However I still see an outline of the middle circle in the region which was filled!? Here is a hopefully MWE.

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[x=1mm,y=1mm,scale=5]
\coordinate (A) at (-6.928,0);
\coordinate (B) at (0,0);
\coordinate (C) at (6.928,0);
\clip (B) circle (6.0);
\draw[ultra thick] (B) circle (6.0);
\filldraw [fill=white,draw=black,thick] (A) circle (6);
\filldraw [fill=white,draw=black,thick] (C) circle (6);
\end{tikzpicture}
\end{document}

And the result is the following, which shows the faint outline of the clipping region. What am I missing?!

enter image description here

  • 1
    I can't see the outline with Sumatra, but I see it with Chrome. So it must be a viewer problem. – Kpym Jan 5 '15 at 8:57
4

You say "I would like to clip the region which is inside the middle circle, but outside the other two". Using answers from this question, and this one, you can do it by using a reverseclip like this :

\documentclass[border=1cm]{standalone}
\usepackage{tikz}

\tikzset{
  reverseclip/.style={insert path={(-99cm,-99cm) rectangle (99cm,99cm)}}
}
\begin{document}
  \begin{tikzpicture}[x=1mm,y=1mm,scale=5]

    %before the clip
    \fill[blue!30] (-10,-10) rectangle (10,10);

    \coordinate (A) at (-6.928,0);
    \coordinate (B) at (0,0);
    \coordinate (C) at (6.928,0);

    % clip
    \begin{pgfinterruptboundingbox}
      \clip (B) circle (6.0);
      \clip[reverseclip] (A) circle (6);
      \clip[reverseclip] (C) circle (6);
    \end{pgfinterruptboundingbox}

    % after the clip
    \fill [orange] (-10,-10) rectangle (10,10);

  \end{tikzpicture}
\end{document}

enter image description here

But if what you want is to understand why you see the outline of the middle circle, then my answer will not helps you.

UPDATE: Here are original next to reversclipped figures:

\documentclass[border=7mm,varwidth]{standalone}
\usepackage{tikz}

\tikzset{
  reverseclip/.style={insert path={(-99cm,-99cm) rectangle (99cm,99cm)}}
}
\begin{document}
  \begin{tikzpicture}[x=1mm,y=1mm,scale=5]
    \coordinate (A) at (-6.928,0);
    \coordinate (B) at (0,0);
    \coordinate (C) at (6.928,0);
    \clip (B) circle (6.0);
    \draw[ultra thick] (B) circle (6.0);
    \filldraw [fill=white,draw=black,thick] (A) circle (6);
    \filldraw [fill=white,draw=black,thick] (C) circle (6);
  \end{tikzpicture}
  \hspace{-4cm}
  \begin{tikzpicture}[x=1mm,y=1mm,scale=5]
    \coordinate (A) at (-6.928,0);
    \coordinate (B) at (0,0);
    \coordinate (C) at (6.928,0);

    % clip
    \begin{pgfinterruptboundingbox}
      \clip (B) circle (6.0);
      \clip[reverseclip] (A) circle (6);
      \clip[reverseclip] (C) circle (6);
    \end{pgfinterruptboundingbox}

    % after the clip
    \draw[ultra thick] (B) circle (6.0);
    \filldraw [fill=white,draw=black,thick] (A) circle (6);
    \filldraw [fill=white,draw=black,thick] (C) circle (6);
  \end{tikzpicture}
\end{document}

in Chrome :

enter image description here

and converted with ghostscript (same as Sumatra view) :

enter image description here

  • This might be the source for reverseclip: tex.stackexchange.com/q/12010/4918 – Tobi Jan 5 '15 at 8:07
  • This answer is very helpful, because it actually describes a better of doing what I was doing. It does not explain why I see the outline, but it seems that this may be a rendering problem (I use Skim on Mac OS X, but also Preview suffers from the same problem.) – José Figueroa-O'Farrill Jan 5 '15 at 9:39
  • @JoséFigueroa-O'Farrill Yes, it is a viewer problem. I came to add some comparision results. – Kpym Jan 5 '15 at 9:42
4

Although there are workarounds, I think the issue raised here is a viewer artifact. The following code simply uses PDF literals to draw a similar picture and produces similar results depending on the viewer magnification. Printing is fine though (although some applications may regard the resulting PDF as corrupt/damaged).

\documentclass[border=10]{standalone}
\begin{document}
\pdfliteral{
q  
  % clip
  -5 -5 m -5 5 l 5 5 l 5 -5 l h 
  W n
  % centre rectangle
  2 w 1 g
  -5 -5 m -5 5 l 5 5 l 5 -5 l h 
  S
  % upper rectanlge 
  1 w 1 g
  1 1 m 1 11 l 11 11 l 11 1 l h 
  B 
  % lower rectangle
  1 w 1 g 
  -1 -1 m -1 -11 l -11 -11 l -11 -1 l h 
  B 
Q 
}
\end{document}

The examples shown here use the evince document viewer. I presume other viewers may show the similar artifacts at 256% magnification:

enter image description here

512% magnification,

enter image description here

1024% magnification,

enter image description here

and at at 2048% magnification:

enter image description here

  • With Chrome we can see the initial problem, but not this one. Sumatra has no this kind of problems. And when we convert images to PNG with ghostscript, no problem is visible. – Kpym Jan 5 '15 at 9:20
  • If the resulting PDF is opened in gimp (and thus rasterised) the artifacts are still present regardless of the resolution settings. Since I am using Linux this probably means the poppler library is the culprit. – Mark Wibrow Jan 5 '15 at 13:38
  • Chrome use agg library for pdf rendering, but still has this issue. Adobe 8 also has it ! But when opened with PhotoShop CS5, the problem is absent. – Kpym Jan 5 '15 at 13:55
  • @Kpym Depends also anti-aliasing settings and many other stuff too, it is similar to subpixel rendering problem it is a matter of implementation details. – percusse Jan 5 '15 at 16:15
3

An alternative this solution proposes is to find the intersection points (4 in total ) of the three circles and then use the 4 points to form a rectangle that covers the main body and clip it.

enter image description here

Code

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}[x=1mm,y=1mm,scale=5]
\coordinate (A) at (-6.928,0);
\coordinate (B) at (0,0);
\coordinate (C) at (6.928,0);

% find intersection points of circles, to form a rectangle

\path[ultra thick,name path=b] (B) circle (6.0);
\path [name path=a] (A) circle (6);
\path [name path=c] (C) circle (6);
\fill[name intersections={of=a and b}];
\coordinate[yshift=1cm] (x1)  at (intersection-1);
\coordinate[yshift=-1cm] (y1) at (intersection-2);
\fill[name intersections={of=b and c}];
\coordinate[yshift=1cm]  (x2) at (intersection-1);
\coordinate[yshift=-1cm] (y2) at (intersection-2);

% clip the  rectangle formed by the extended 4 corners

\clip (x1)--(y1)--(y2)--(x2);
\draw[ultra thick] (B) circle (6.0);
\filldraw [fill=white,draw=black,thick] (A) circle (6);
\filldraw [fill=white,draw=black,thick] (C) circle (6);
\end{tikzpicture}
\end{document}
3

It was pointed by all answers that the initial problem was a viewer problem.
In my first answer I explained how to overcome the problem using reverseclip.

I'll try now to explain why this problem occurs in viewers.
This is a guess, but I think with hight probability ;)

First thing first: anti-aliasing

If we draw a white circle over a black circle with the same diameter, due to anti-aliasing, all viewers that I have checked (Sumatra, Acrobat 8, Chrome, EBookDroid, Acrobat for Android, MuPDF, ezPDF, Google Document for Android) display a thin gray residue of the black circle. This happens probably because, they first draw the black circle with anti-aliasing, then the white one with anti-aliasing.

\begin{tikzpicture}
  \fill[black] circle(1);
  \fill[white] circle(1);
\begin{tikzpicture}

enter image description here

But the bitmap transformers (Photoshop CS5, ghostscript, Acrobat 8 export to PNG), display no visible halo, probably because they render first the two circles and anti-alise after.

Clipping

When viewers clip some paths they have two choices:

  • clip all path one by one and render them after, or
  • group all paths and clip the result after.

So in the following code

\begin{tikzpicture}
  \clip circle(1);
  \fill[black] circle(1);
  \fill[white] circle(2);
\begin{tikzpicture}

some viewers (like Chrome and Acrobat 8, ezPDFReader, Google Document for Android) will clip the two circles separately and render them after, which result in the same thing as the first code. And other viewers (like Sumatra, Acrobat for Android, EBookDroid, MuPDF) will group first the paths and clip them after, wich result in a empty page (white circle on white background), like for the bitmap transformers (ghostscript, Photoshop CS5 and Acrobat 8 export to PNG).

To proof this, we can force the viewers to group the path before clipping by using transparency group and then there is no visible halo in any cases. Here is the test code:

\documentclass[varwidth,border=7mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
  % A: same in all viewers (visible halo)
  \begin{scope}[shift={(0,0)}]
    \fill[black] circle(1);
    \fill[yellow!20] circle(1);
    \node{A};
  \end{scope}

  % B: same in all viewers (visible halo)
  \begin{scope}[shift={(3,0)}]
    \fill[black] circle(1);
    \clip circle(1);
    \fill[yellow!20] circle(2); % clipped is the same as circle(1)
    \node{B};
  \end{scope}

  % C: depends on viewer (clip separately paths or clip grouped paths ?)
  \begin{scope}[shift={(0,-3)}]
    \clip circle(1);
    \fill[black] circle(1);
    \fill[yellow!20] circle(2);
    \node{C};
  \end{scope}

  % D: same in all viewers (no halo, due to grouping paths before clipping)
  \begin{scope}[shift={(3,-3)}]
    \clip circle(1);
    \begin{scope}[transparency group]
      \fill[black] circle(1);
      \fill[yellow!20] circle(2);
    \end{scope}
    \node{D};
  \end{scope}

\end{tikzpicture}
\end{document}

The result in ghostscript, Photoshop CS5 and Acrobat export to PNG:

enter image description here

The result in Sumatra,Acrobat for Android, EBookDroid and MuPDF:

enter image description here

The result in Chrome, Acrobat 8, ezPDFReader and Google Docs for Android:

enter image description here

2

If (and only if) the OP's example is indicative of the required use case then a bit of geometry can be used:

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{calc}
\begin{document}
\tikz[x=1mm,y=1mm,scale=5]
  \draw let \n1={acos(6.928/2/6)} in [thick]
    (\n1:6) arc (\n1:180-\n1:6) arc (\n1:-\n1:6) arc (180+\n1:360-\n1:6) arc (180+\n1:180-\n1:6) -- cycle;
\end{document}

enter image description here

1

(possible) Explanation

From an implementation-wise view the result is understandable. The center circle's coordinates are completely within the clipping region, therefore you don't clip it. The problem is that the ultra thick line extends the clipping region. The other circles however are correctly clipped and can't overdraw the part of the ultra thick line with lies outside of the clipping region.

(poor man's) Workaround

Fill the two outer circles with a bigger clipping region.

\begin{tikzpicture}
\coordinate (A) at (-6.928,0);
\coordinate (B) at (0,0);
\coordinate (C) at (6.928,0);
\draw[thick] (B) circle (6.0);
\clip (B) circle (6.1);
\fill [fill=white] (A) circle (6);
\fill [fill=white] (C) circle (6);
\clip (B) circle (6.0);
\filldraw [fill=white,draw=black,thick] (A) circle (6);
\filldraw [fill=white,draw=black,thick] (C) circle (6);
\end{tikzpicture}

Before

After

  • I don't think this is the problem. In fact, your workaround still gives the faint outline of the middle circle. The "ultra thick" was just so that with the clipping, the border of the region was uniform. – José Figueroa-O'Farrill Jan 5 '15 at 11:14
  • @JoséFigueroa-O'Farrill it already has been stated to be a viewer dependent problem. I added two images to show that the workaround does work at least for one viewer (pdfXchange) :) In very zoomed out views there might be resolution artifacts, so I increased to clipping circle radius a bit. – Harald Jan 5 '15 at 12:33

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.