Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I've searched, but I can't find a previous question sufficiently close to this one to find an answer. At the same time, this problem seems like it must have been solved by someone before now, so apologies if it's a duplicate.

I want to clip a path (particularly a circle, but a general solution would be useful too) using a node with a shape. Here's an example:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{through}
\begin{document}

\begin{tikzpicture}
\node [draw,circle,fill=white,minimum size=1mm] (u) at (0,0) {};
\node [draw,circle through=(u)] at (1,0) {};
\end{tikzpicture}

\end{document}

Two circles MWE

I'd like to have the red circle clipped by the black, but still have at least the black circle remain a node. I also want to specify the black node first if at all possible.

I'm guessing that something like a postaction might be what I need, but I haven't been able to make enough sense of those yet to work it out.

Edit: clarification and something a bit strange

What I want is something looking like this:

enter image description here

Which can obviously be got with code like:

\begin{tikzpicture}
\node [circle,minimum size=5mm] (u) at (0,0) {};
\node [draw, circle through=(u),red] at (1,0) {};
\node [draw,circle,fill=white,minimum size=5mm] at (0,0) {};
\end{tikzpicture}

But that necessitates the first node being specified twice.

The use case for this is a load of graphs I've already done, using a vertex style for all the vertex nodes and ideally I want to just edit this style to do the reverse clipping.

Finally, there's something very strange about the technique used at this answer

This code works as expected

\begin{tikzpicture}[remember picture,overlay]

% A path that follows the edges of the current page
\tikzstyle{reverseclip}=[insert path={(current page.north east) --
  (current page.south east) --
  (current page.south west) --
  (current page.north west) --
  (current page.north east)}
]

\node [circle,minimum size=8mm] (u) at (0,0) {};

\coordinate (A) at (0,0);
\coordinate (B) at (1,0);
\coordinate (C) at (1,1);


\begin{pgfinterruptboundingbox} % To make sure our clipping path does not mess up the placement of the picture
\path [clip,draw] (A) -- (B) -- (C) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}

\draw [fill=red] (1,0) circle  (1cm);

\end{tikzpicture}

but this doesn't

\begin{tikzpicture}[remember picture,overlay]

% A path that follows the edges of the current page
\tikzstyle{reverseclip}=[insert path={(current page.north east) --
  (current page.south east) --
  (current page.south west) --
  (current page.north west) --
  (current page.north east)}
]

\node [circle,minimum size=8mm] (u) at (0,0) {};

\coordinate (A) at (u.east);
\coordinate (B) at (u.south west);
\coordinate (C) at (u.north west);

\begin{pgfinterruptboundingbox} % To make sure our clipping path does not mess up the placement of the picture
\path [clip,draw] (A) -- (B) -- (C) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}

\draw [fill=red] (1,0) circle  (1cm);

\end{tikzpicture}

which makes absolutely no sense to me. The first reverse-clips as expected, the second just draws the filled circle on top as if no clipping is happening at all.

share|improve this question
    
Does How can I invert a 'clip' selection within TikZ? provide any assistance? –  Werner Mar 2 '12 at 18:40
    
I haven't tried it yet, but I suspect the technique I used in this answer would work. It's not something you can do in the middle of a tikzpicture, though, so it may not be as flexible as you'd want. –  Ben Lerner Mar 2 '12 at 18:47
    
@Werner possibly, but I'm having trouble seeing how to use that in my case. I'm not claiming it doesn't work, just that I'm not tikz-savvy enough to understand how! –  Joseph Cooper Mar 2 '12 at 18:49
    
@JosephCooper: You can use \clip (u.west) -- (u.north) -- (u.east) -- (u.south)--cycle; –  Marco Daniel Mar 2 '12 at 19:02

5 Answers 5

Here is a very simple solution via backgrounds TikZ library:

enter image description here

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{through,backgrounds}

\begin{document}
\begin{tikzpicture}
  \node [draw,circle,fill=white,minimum size=1mm] (u) at (0,0) {};
  \begin{scope}[on background layer]
    \node [draw=red,circle through=(u)] at (1,0) {};
  \end{scope}
\end{tikzpicture}
\end{document}
share|improve this answer

This isn't really a proper answer, more a comment, but I have no reputation and therefore can't leave comments yet. Also, I realise this is an old question, but this might help someone avoid the confusion that I've just experienced!

In response to the "there's something very strange about the technique used at this answer" remark: I came across a similar phenomenon, and became increasingly confused over a couple of hours until I eventually twigged. When you specify two concentric loops for \path[clip], it either restricts (clips) to the area between them, or ignores the inner one and restricts to the whole area enclosed by the outer one. It does the former if the orientations of the two loops are different, and the latter if they are the same.

I think this is reversed by the even odd rule: The example here uses the even odd rule to clip between two circles, and I assume that it's necessary in this case because the two loops are both created using circle, and therefore have the same orientation (or are not assigned one; I don't know exactly what goes on in the background).

share|improve this answer
    
Welcome to TeX.SX! Certainly, too long for a comment, and actually a partial answer, so +1. –  mafp Jul 3 '13 at 14:56

With reverseclip ! (werner's suggestion and and the great answer from Jake)

enter image description here

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,through}   

\begin{document}
\begin{tikzpicture}[remember picture,overlay]

% A path that follows the edges of the current page
\tikzstyle{reverseclip}=[insert path={(current page.north east) --
  (current page.south east) --
  (current page.south west) --
  (current page.north west) --
  (current page.north east)}
]
\node [draw,circle,fill=white,minimum size=6mm,inner sep=0pt] (u)  at (0,0) {};

\begin{pgfinterruptboundingbox} % To make sure our clipping path does not mess up the placement of the picture
\path [clip]  let  \p1 = ($ (u.center) - (u.east) $) in   circle ({veclen(\x1,\y1)})-- cycle [reverseclip];
\end{pgfinterruptboundingbox}

\node [draw,circle through=(u)] at (1,0) {};  
\end{tikzpicture}
\end{document}   

update With reverseclip from Jake and append after command from percusse

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,through}   

\begin{document}
\begin{tikzpicture}[remember picture,overlay]

\tikzstyle{reverseclip}=[insert path={(current page.north east) --
  (current page.south east) --
  (current page.south west) --
  (current page.north west) --
  (current page.north east)}
]
\path[clip,draw]  node [draw,circle,fill=white,minimum size=6mm,inner sep=0pt,
   append after command={%
   let  \p1 = ($ (u.center) - (u.east) $) in circle ({veclen(\x1,\y1)})-- cycle   
               [reverseclip]}] (u)  at (0,0) {};
\node [red,draw,circle through=(u)] at (1,0) {};  
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
    
No, the 'inverse' of that, where part of the larger circle isn't drawn where it is inside the smaller one. –  Joseph Cooper Mar 2 '12 at 19:31
    
Ok You need only to add inverseclip –  Alain Matthes Mar 2 '12 at 20:44

In the manual there is this nice option append after command. It says that it's for experts so don't tell anyone that I used it :) Here's some more black magic:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\draw[thick,red] node [
        draw=black,
        circle,
        fill=white,
        minimum size=1cm,
        append after command={
            let \p1 = (u), \p2 = (2,0), \p3 = ($ (\p2) - (\p1) $),\n1 = {veclen(\x3,\y3)} 
            in (\p2) circle (\n1)
            }
] (u) at (0,0) {};
\end{tikzpicture}
\end{document}

enter image description here

I have made the shapes slightly bigger to make it more visible. I didn't actually go for making the red circle a node itself just because you know where its center would be so you can add it easily.

share|improve this answer
    
If I understand correctly, you're doing the circle through manually in the append after. Is that correct? –  Joseph Cooper Mar 2 '12 at 20:03
    
@JosephCooper Yes, kind of. append after lets you to use the node name before it is drawn but after its coordinates are known. So I am calculating the radius using that information. The rest is pretty straightforward. –  percusse Mar 2 '12 at 20:07

Try drawing the small circle after the large one, so its fill will cover the arc inside of it. Basically, you should place a \coordinate at the location you want its center to be, and then draw both circles relative to that point.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{through}
\begin{document}

\begin{tikzpicture}
\coordinate (u) at (0,0);
\node [draw,circle through=(u)] at (1,0) {};
\node [draw,circle,fill=white,minimum size=1mm] at (u) {};
\end{tikzpicture}

\end{document}

enter image description here

share|improve this answer
    
I knew I could do this, but I was hoping to avoid the 'long' way if I could work out some way of automating it in some sense. Still, thankyou for a solution to the problem. –  Joseph Cooper Mar 2 '12 at 19:55
    
@JosephCooper: I don't think it's the "long" way, actually. It's just a different way of thinking about the structure of the picture. I've found it's often useful in TikZ to start with some setup commands that just define coordinates, and then place various objects at them. Also: in comparison with the code you just added to the question, this does not draw the circle twice. You don't need all of the small circle to draw the large circle through its center; you just need the center. There is no repetition in my answer. –  Ryan Reich Mar 2 '12 at 19:58
    
No, I understand, and that wasn't supposed to be a criticism. It's just that I've got a lot of these things to change, and I deliberately defined a style for all the vertices with the hope of planning ahead. I definitely think that this is a valid way of doing things, and defining coordinates at the start is probably the way I'll do things in the future. It's just the "long way" for changing things already done! –  Joseph Cooper Mar 2 '12 at 20:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.