67

I wish to draw an arc for a reflex angle on the outside of a triangle with coordinates (A), (B) and (C).

If I wanted to draw the arc inside the triangle I could use something like

\begin{scope}
\path[clip] (A) -- (B) -- (C) -- cycle;
\draw (B) circle (2mm);    % this is the little angle marker
\end{scope}

Is there a straightforward way to exclude the part of the circle that's in the triangle, as in the pseudo-code below?

\begin{scope}
\path[magicalinverseclipcommand] (A) -- (B) -- (C) -- cycle;
\draw (B) circle (2mm);    % this is the little angle marker
\end{scope}

EDIT: Although I included the code above as a motivating example of what an inverse clip would do, I would prefer a general solution that works systematically with any closed path, and not just in the particular example of a triangle with a circle clipped out of it. Looking at my question, I realise this isn't clear, and I will be happy with the best solution to my particular problem, but wonder if there is a less ad hoc solution than those listed so far.

bryn
  • 10,264
  • 14
  • 46
  • 43
  • 2
    Good question! I was trying to do something like this to construct an answer to http://tex.stackexchange.com/q/3528/86 (a question about cutting out a circle from an ellipse) but haven't found anything yet. – Andrew Stacey Feb 25 '11 at 08:55
  • 1
    Thanks! I'm having to do messy things like creating new closed paths to clip against, but I'd prefer to have a systematic solution so I can use it in \newcommands easily. – bryn Feb 25 '11 at 09:03
  • Maybe you could edit your question to explain in a little more detail what you are looking for that is not provided by the answers already given? The bounty you set out is likely to attract people to the question, but when they see three posts that seem to answer your question, they are less likely to provide answers of their own. – Jake Mar 05 '11 at 12:57
  • couldn't you just draw the arc behind the triangle (and fill the triangle: fill=white)? – romeovs Mar 09 '11 at 06:50
  • 1
    Bryn, I still don't see what isn't answered by Jake's answer. His method provides a way to invert an arbitrary clip, so anything you previously wanted to clip against can be inverted. Do you have an example where it fails? Or a more complicated example where you can't see how to implement it? – Andrew Stacey Mar 09 '11 at 09:41
  • To be honest I thought all the solutions seemed a bit complicated, and so the bounty was to try and elicit the best (and simplest [and most robust]) possible solution. And when I saw this "1 meter larger" line I didn't like the look of it. But now that I look further down it actually looks pretty good, so I'll award the bounty to this solution. – bryn Mar 10 '11 at 02:47
  • @bryn: Fair point. I've removed the 1 metre approach. – Jake Mar 10 '11 at 09:07
  • 1
    @Jake: Thanks -- I think this looks like a good solution now, and hopefully will be stored for posterity (until Till Tantau implements it natively maybe!). – bryn Mar 12 '11 at 03:21

8 Answers8

59

What you can do is add a rectangle to your clipping path that's larger than the current bounding box, and clip with that. Andrew Stacey suggested using the current page as the clipping rectangle, because that will catch all elements that follow. By using the pgfinterruptboundingbox environment when defining the clipping rectangle, the actual size of the tikzpicture will not be influenced.

Note that, in order to use the current page, the remember picture,overlay options need to be passed to the tikzpicture, and you need two compile runs to get the positioning of all the elements right. Furthermore, this doesn't work with the minimal documentclass.

\documentclass{article} % Has to be a proper class, not minimal
\usepackage{tikz}

\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)}
]

\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] (A) -- (B) -- (C) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}

\draw[thick] (A) circle (2mm);
\draw[thick] (B) circle (2mm);    
\draw[thick] (C) circle (2mm);   

\end{tikzpicture}
\end{document}


And just to show that it works for the general case:

\documentclass{article}
\usepackage{tikz}

\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)}
]

\draw [step=0.1,red] (0,0) grid  (2,2);

\begin{pgfinterruptboundingbox} % To make sure our clipping path does not mess up the placement of the picture
\path [clip,rounded corners] (0,0) -- (.75,0) -- (1.2,.8) -- (2,1) -- (1.4,1) -- (1.2,2) -- (.3,.75) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}

\draw [step=0.1,thick] (0,0) grid  (2,2);

\end{tikzpicture}
\end{document}

general path clipped

Jake
  • 232,450
  • If you're doing it in one action (as you are here, unlike my answer) why not use the page itself as the "infinitely large" box? Although 1m seems pretty big, I have some pictures that are on canvas bigger than that! Or maybe it's a big picture scaled down a lot. Would that work? (PS I like the answer - much better than mine) – Andrew Stacey Feb 25 '11 at 13:13
  • @Andrew: I tried using the current page originally, but somehow couldn't get it to work and so settled for the pretty big rectangle. But you're right, there's always going to be something that's a bit bigger than that. So following your comment, I revisited my answer and found out that the current page node does not work with the minimal class, but otherwise it's fine. I've added the approach to my answer. – Jake Feb 25 '11 at 13:36
  • Great! I'd vote again but I'm not allowed. Now I'm wondering whether the choice of "even odd rule" or the other one leads to strange behaviour ... but I can experiment with that myself! – Andrew Stacey Feb 25 '11 at 14:01
  • Oh, and you have 10 minutes to adapt this to an answer to http://tex.stackexchange.com/q/3528/86 before I steal your idea and do so myself. – Andrew Stacey Feb 25 '11 at 14:01
  • @Andrew: I think the OP of the question you linked to wants the resulting shape to have an outline, and I don't see how that can be achieved. I've bookmarked the question, however, and am looking forward to seeing your solution! – Jake Feb 25 '11 at 14:17
  • Ah, I didn't spot that wriggle. Still, it ought to be possible. – Andrew Stacey Feb 25 '11 at 14:58
  • Ta da! ​​​​​​​​​​​​ – Andrew Stacey Feb 25 '11 at 15:24
  • @Andrew: Well done! – Jake Feb 25 '11 at 15:38
  • @Jake: You "need two compile runs". (Yes, I can edit, but 1 letter seemed to little to me.) – Hendrik Vogt Mar 09 '11 at 13:00
  • @Jake I think you can remove overlay. I added a new answer without remember picture. – Alain Matthes Mar 29 '11 at 16:47
  • @AndrewStacey A solution (without overlay and remember picture) is maybe to use (-16383.99pt,-16383.99pt) rectangle (16383.99pt,16383.99pt)! – Paul Gaborit Jun 09 '12 at 00:39
  • @PolGab: I get dimension too large error when I use that. – Jake Jun 09 '12 at 06:14
  • @Jake This big rectangle can be used only to clip and without any shifting operations and without remember picture and overlay options. – Paul Gaborit Jun 09 '12 at 08:57
  • @PolGab: Maybe you can add an answer, or edit this one. I can't get that to work. – Jake Jun 09 '12 at 09:00
  • @Jake I've been using the reverseclip solution but was recently bitten by the fact that "current page" does not work in the "minimal" class. Can you add a comment to the source code on the documentclass line, highlighting this fact? – Tom Oct 10 '12 at 17:38
  • @Tom: Good point. Done! – Jake Oct 10 '12 at 17:43
  • @Jake. Not sure if this is worth mentioning as well, but this reverse clip method only works as expected when your path is a CCW path. I ran into this here: http://tex.stackexchange.com/questions/75794/how-to-reverse-clip-on-custom-path-defined-by-ellipse-intersections/76230#76230 – Tom Oct 12 '12 at 04:48
  • I've discovered that this also doesn't work with externalising graphics. Then, one has to define a specific box. In the situation I'm using then the current bounding box is sufficient, so I have \tikzset{reverse clip/.style={insert path={[#1.north east] -- ...}},reverse clip/.default=current page} which allows me to change the clip box at will. – Andrew Stacey Nov 29 '13 at 07:51
  • This does not work for me with the standalone document class (Dimension too large error). Runs fine with article instead. – Matthias Arras Jul 21 '18 at 18:37
  • Also it appears that the pgfinterruptboundingbox approach is not compatible with the tikz-3d library, as the path in the interruptboundingbox is not projected correctly in 3d space. – Matthias Arras Jul 21 '18 at 19:07
  • Regarding the previous comment, line paths seem to work fine, just ja circular clipping gives me troubles in tikz-3d. – Matthias Arras Jul 21 '18 at 19:18
34

To avoid remember picture and overlay, I mix Jack's solution and Altermundus's solution using the bigger rectangle that TikZ/PGF (TeX?) can used (Edit: as suggested by Qrrbrbirlbel, I add [reset cm] to get a solution independent from any scale transformations).

First tikzpicture shows two (inv)clipping triangles.

Second tikzpicture shows the effect of nonzero rule (even odd rule can't be used directly in a clipping path, see note below).

\documentclass{standalone}
\usepackage{tikz}
\begin{document}

\tikzset{invclip/.style={clip,insert path={{[reset cm]
      (-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)
    }}}}

\begin{tikzpicture}[outer sep=0mm]
  \coordinate (A) at (0,0);
  \coordinate (B) at (1,0);
  \coordinate (C) at (.5,1);
  \coordinate (Ap) at (0,1);
  \coordinate (Bp) at (1,1);
  \coordinate (Cp) at (.5,0);
  \begin{scope}
  \begin{pgfinterruptboundingbox} % useful to avoid the rectangle in the bounding box
    \path[invclip]
    (A) -- (B) -- (C) -- (A)
    (Ap) -- (Cp) -- (Bp) -- (Ap);
  \end{pgfinterruptboundingbox} 

  \fill[orange!50] (-1,-1) rectangle (2,2);

  \draw (A) circle (2mm);    % this is the little angle marker
  \draw (B) circle (2mm);    % this is the little angle marker
  \draw (C) circle (2mm);    % this is the little angle marker

  \draw (Ap) circle (2mm);    % this is the little angle marker
  \draw (Bp) circle (2mm);    % this is the little angle marker
  \draw (Cp) circle (2mm);    % this is the little angle marker

  \end{scope}

  \draw[red] (current bounding box.south west)
  rectangle (current bounding box.north east);
\end{tikzpicture}

\begin{tikzpicture}[outer sep=0mm]
  \coordinate (A) at (0,0);
  \coordinate (B) at (1,0);
  \coordinate (C) at (.5,1);
  \coordinate (Ap) at (0,1);
  \coordinate (Bp) at (1,1);
  \coordinate (Cp) at (.5,0);
  \begin{scope}
  \begin{pgfinterruptboundingbox} % useful to avoid the rectangle in the bounding box
    \path[invclip]
    (A) -- (B) -- (C) -- (A)
    (Ap) -- (Bp) -- (Cp) -- (Ap);
  \end{pgfinterruptboundingbox} 

  \fill[orange!50] (-1,-1) rectangle (2,2);

  \draw (A) circle (2mm);    % this is the little angle marker
  \draw (B) circle (2mm);    % this is the little angle marker
  \draw (C) circle (2mm);    % this is the little angle marker

  \draw (Ap) circle (2mm);    % this is the little angle marker
  \draw (Bp) circle (2mm);    % this is the little angle marker
  \draw (Cp) circle (2mm);    % this is the little angle marker

  \end{scope}

  \draw[red] (current bounding box.south west)
  rectangle (current bounding box.north east);
\end{tikzpicture}
\end{document}

enter image description here

Note about rules and clip:

It's impossible to combine clip and even odd rule in a path (it seems to me that it's almost a bug). But, if you add the even odd rule option to the enclosing scope, the clip operation uses it. Applied on the previous example, the clipping paths can use any direction of rotation:

\documentclass{standalone}
\usepackage{tikz}
\tikzset{invclip/.style={clip,insert path={{[reset cm]
        (-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)}}}}
\begin{document}
\begin{tikzpicture}[outer sep=0mm]


  \coordinate (A) at (0,0);
  \coordinate (B) at (1,0);
  \coordinate (C) at (.5,1);
  \coordinate (Ap) at (0,1);
  \coordinate (Bp) at (1,1);
  \coordinate (Cp) at (.5,0);
  \begin{scope}[even odd rule]

    \begin{pgfinterruptboundingbox} % useful to avoid the rectangle in the bounding box
      \path[invclip]
      (A) -- (B) -- (C) -- (A)
      (Ap) -- (Bp) -- (Cp) -- (Ap);
    \end{pgfinterruptboundingbox} 

    \fill[orange!50] (-1,-1) rectangle (2,2);

    \draw (A) circle (2mm);    % this is the little angle marker
    \draw (B) circle (2mm);    % this is the little angle marker
    \draw (C) circle (2mm);    % this is the little angle marker

    \draw (Ap) circle (2mm);    % this is the little angle marker
    \draw (Bp) circle (2mm);    % this is the little angle marker
    \draw (Cp) circle (2mm);    % this is the little angle marker

  \end{scope}

  \draw[red] (current bounding box.south west)
  rectangle (current bounding box.north east);
\end{tikzpicture}
Paul Gaborit
  • 70,770
  • 10
  • 176
  • 283
  • 2
    Using insert path={{[reset cm] (-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)}} makes this solution independent from any [x|y] scale options. – Qrrbrbirlbel Jun 18 '13 at 21:55
  • @Qrrbrbirlbel This is a very good suggestion! – Paul Gaborit Jun 19 '13 at 22:28
  • I really like this answer, but I don't fully understand how it works. In the PGF manual it says the following about pgfinterruptboundingbox: "This environment temporarily interrupts the computation of the bounding box and sets up a new bounding box. At the beginning of the environment the old bounding box is saved and an empty bounding box is installed. After the environment the original bounding box is reinstalled as if nothing has happened." What does this last part mean? It cannot be that it completely undoes whatever it is that you did within the pgfinterruptboundingbox, right? – gablin Oct 10 '14 at 11:53
  • 1
    @gablin It means that it does not affect the bounding box of the overall resulting picture i.e. doesn't make it bigger (or smaller). – cfr Jan 10 '16 at 22:42
  • I struggled for an hour to make this work for my own figure, and I just couldn't get it to work until I figured out the following: In this context, it makes a difference how you draw the clipping path to be inverted. In this example, (Ap) -- (Cp) -- (Bp) -- (Ap) works just fine, but (Ap) -- (Bp) -- (Cp) -- (Ap) does not work. I don't understand why this matters, though... – gablin Jan 12 '18 at 11:31
  • 1
    @gablin You may read the description of the nonzero rule in pgfmanual (p.172, v3.0.1a). The direction of rotation of the paths is fundamental. – Paul Gaborit Jan 12 '18 at 14:21
  • @gablin I added a note about even odd rule and clip... – Paul Gaborit Jan 24 '18 at 17:31
  • I am a novice, and I do not fully understand, what is happening here but it seem to me that clip is by default always using even odd rule and it is therefor not to be set by an option. It is also not needed to use insert path when not defining a style. Example where I believe it is working: https://tex.stackexchange.com/a/568980/8650 – hpekristiansen Oct 30 '20 at 20:48
  • I was mistaken - it is not the even odd rule but the default nonzero rule that makes it work when using ellipses/circles (apparently they are drawn in opposite direction of rectangles). – hpekristiansen Oct 30 '20 at 23:30
14

@Jack send me here from a question regarding invclip: Reverse clipping in a 3D figure - Projection issue.

That question shows a problem of @PaulGaborit's answer that double braces in

\tikzset{invclip/.style={clip,insert path={{[reset cm]
      (-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)
    }}}}

does not limit the scope of reset cm. In fact, it took four in the case in the link above. Therefore, in the link above, I suggested the following code

\tikzset{
    clip even odd rule/.code={\pgfseteorule}, % Credit to Andrew Stacey 
    invclip/.style={
        clip,insert path=
            [clip even odd rule]{
                [reset cm](-\maxdimen,-\maxdimen)rectangle(\maxdimen,\maxdimen)
            }
    }
}

A complete example goes like this

\documentclass[border=9,tikz]{standalone}
\usetikzlibrary{graphs,graphs.standard}
\begin{document}

\tikzset{
    clip even odd rule/.code={\pgfseteorule}, % Credit to Andrew Stacey 
    invclip/.style={
        clip,insert path=
            [clip even odd rule]{
                [reset cm](-\maxdimen,-\maxdimen)rectangle(\maxdimen,\maxdimen)
            }
    }
}

\tikz{
    \begin{pgfinterruptboundingbox}
        \clip[invclip](1,0)--(0,1)--(0,-1)--(-1,0)--cycle;
    \end{pgfinterruptboundingbox}
    \graph{subgraph K_n[n=20,clockwise,radius=50]};
}

\end{document}
Symbol 1
  • 36,855
8

The solution to draw an arc outside the triangle is to use my new package tkz-euclide and with this way, you don' need to invert a clip selection

\documentclass{minimal}
\usepackage{tkz-euclide} 
\usetkzobj{all}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}

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

\draw (A) -- (B) -- (C) -- cycle;
\draw (B) circle (2mm);    % this is the little angle marker
\tkzDrawArc[R with nodes,color=red](B,1cm)(A,C)  
\tkzDrawArc[R with nodes,color=blue](B,1cm)(C,A) 
\end{tikzpicture}
\end{document}

arcs

Now if you want, I can extract the code from my package. You need to use an internal macro of pgf named \pgfmathanglebetweenpoints; in my package I use \tkzmathanglebetweenpoints because I want a good precision so I work with fp and not with pgfmath from some parts of the code. Then the problem it's to use angles with + or - because I want to draw from (B,A) towards (B,C) or from (B,C) towards (B,A). If you want all the details, I give you in some hours because now, I need to work with my students

I complete my answer without tkz-euclide

\documentclass{minimal}
\usepackage{tikz} 
\usetikzlibrary{calc}

\makeatletter
\def\drawarc{\pgfutil@ifnextchar[{\draw@arc}{\draw@arc[]}}  
\def\draw@arc[#1](#2,#3)(#4,#5){% 
 \begingroup
 \pgfmathanglebetweenpoints{\pgfpointanchor{#2}{center}}{%
                            \pgfpointanchor{#4}{center}} 
\global\let\FirstAngle\pgfmathresult 
 \pgfmathanglebetweenpoints{\pgfpointanchor{#2}{center}}{%
                            \pgfpointanchor{#5}{center}} 
\global\let\SecondAngle\pgfmathresult        
  \pgfmathgreaterthan{\FirstAngle}{0}   
  \ifdim\pgfmathresult pt=1 pt\relax%  
    \pgfmathgreaterthan{\FirstAngle}{\SecondAngle}
    \ifdim\pgfmathresult pt=1 pt\relax%
     \pgfmathsubtract{\FirstAngle}{360}
     \edef\FirstAngle{\pgfmathresult}%
 \fi 
 \else
     \pgfmathgreaterthan{\FirstAngle}{\SecondAngle}
    \ifdim\pgfmathresult pt=1 pt\relax%
        \pgfmathadd{\SecondAngle}{360}
        \edef\SecondAngle{\pgfmathresult}%
     \fi 
 \fi
     \draw[#1,shift = {(#2)}](\FirstAngle:#3) arc (\FirstAngle:\SecondAngle:#3);
\endgroup  
}  
\makeatother

\begin{document}        
\begin{tikzpicture}

\coordinate (A) at (2,2);
\coordinate (B) at (1,0);
\coordinate (C) at (3,1);    
\draw (A) -- (B) -- (C) -- cycle;
\drawarc[red](B,1cm)(A,C)
\drawarc[blue](B,1cm)(C,A)     
\end{tikzpicture}  
\end{document}

enter image description here

Alain Matthes
  • 95,075
  • It's not the answer at "How to invert a clip selection" but at the subquestion " how to draw an arc outside a triangle" and you don't need to use an invert clip. The Jake'answer is very interesting. – Alain Matthes Mar 04 '11 at 08:29
6

To get the ball rolling on this one, here's a method that uses fadings. What I don't like about it is that to make this work, one has to specify a large rectangle in the fading that one hopes (!) is large enough - I don't know how to automate this. The issue is that when specifying a fading, everything outside the fading is assumed to be transparent, whereas for this one wants everything outside to be visible.

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{fadings}
\begin{document}

\begin{tikzfadingfrompicture}[name=fadeit]
\fill[white] (-10,-10) rectangle (10,10);
\path (0,0) coordinate (A) +(0:2) coordinate (B) +(50:2) coordinate (C);
\fill[black] (B) -- (A) -- (C) -- cycle;
\end{tikzfadingfrompicture}

\begin{tikzpicture}
\draw[path fading=fadeit,fit fading=false] (0,0) circle (1);
\end{tikzpicture}
\end{document}

It's also not so great because one has to split the definition of the cutout from the picture (I wonder if it's possible to fix this using remember picture ...).

reverse clipped picture

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
6

this all can be done very easily using the even odd rule, see http://www.texample.net/tikz/examples/venn-diagram/

Elena
  • 61
  • 6
    Welcome to TeX.sx! Having thought about this quite a bit when it was first posted, I'd really want to see an example before I was convinced that this could be done easily using the even-odd rule. The assumption with a clip is that the outside will be thrown away and that's true for any clipping rule as far as I'm aware, and certainly is true of the venn diagram example. – Andrew Stacey Nov 12 '11 at 21:35
4

I search how to avoid the use of remember picture with the Jake's solution. I find this :

\documentclass{article}
\usepackage{tikz}

\begin{document}
\fbox{\begin{tikzpicture}[invclip/.style={insert path={(-1,-1) rectangle (2,2)}}]
 % a rectangle is necessary

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

\begin{pgfinterruptboundingbox} % useful to avoid the rectangle in the bounding box
\path[clip] (A) -- (B) -- (C) -- cycle [invclip];
\end{pgfinterruptboundingbox}  

\draw[thick] (A) circle (2mm)
             (B) circle (2mm)
             (C) circle (2mm);
\end{tikzpicture}}
\end{document}

( I added fbox to verify the bounding box) enter image description here

Alain Matthes
  • 95,075
  • I had this in the first version of my solution (it's still in the edit history), but I think the general consensus was that the drawback of having to decide on a rectangle size (how do you know if it's big enough?) is serious enough to warrant the use of remember picture – Jake Mar 29 '11 at 16:48
  • @Jake No problem you can write : invclip/.style={insert path={(-10,-10) rectangle (20,20)}}or bigger if necessary. Another possibility, is to use the `fit' library. – Alain Matthes Mar 29 '11 at 17:12
  • See Andrew Stacey's first comment on my answer regarding the size of the box (even 1 metre might not be big enough for some things). I'd be interested to see a solution with the fit library, however! – Jake Mar 29 '11 at 17:16
  • @Jake The fit idea does not work. It was to get the rectangle size but I can't place the rectangle correctly. I think the rectangle size is not a good argument. When you draw something, generally you have an idea of the final size. Why do you need overlay in your solution? Without it the bounding box is correct within no. Another suggestion is insert path={ (current page.south west) rectangle (current page.north east)}. – Alain Matthes Mar 29 '11 at 21:38
  • Sorry, my previous (now deleted) comment was not correct: You need the remember picture, overlay to make sure the current page node is positioned correctly. In reply to your previous comment: I agree, in the vast majority of cases specifying a large clipping rectangle will work just fine, but I wanted a solution that will work for the general case. Using the current page node ensures that the clipping rectangle is always large enough and you don't need to make adjustments to the clipping path for different pictures. – Jake Mar 29 '11 at 21:55
  • @Altermundus The solution (without using remember picture and overlay) uses (-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt). But the clipping scope should not use any shift operations... – Paul Gaborit Jun 09 '12 at 01:15
0

As I needed a solution were I could reuse an existing path (which does not work in the otherwise best answer from @Symbol1), I’ve explored other related questions and found another solution from marmotton, also building on top of @Symbol1 and @paul-gaborit answers.

So basically it boils down to:

\documentclass[tikz]{standalone}

\makeatletter \tikzset{ reuse path/.code={\pgfsyssoftpath@setcurrentpath{#1}}, even odd clip/.code={\pgfseteorule}, reverseclip/.code={\clip[overlay,even odd clip,reuse path=#1] [reset cm] (-\maxdimen,-\maxdimen) rectangle (\maxdimen,\maxdimen);} } \makeatother

\begin{document} \begin{tikzpicture} \coordinate (A) at (0,0); \coordinate (B) at (1,0); \coordinate (C) at (1,1);

\draw [save path=\rectclip] (A) -- (B) -- (C) -- cycle;
\begin{pgfinterruptboundingbox}
\tikzset{reverseclip=\rectclip}
\end{pgfinterruptboundingbox}
\draw (A) circle (2mm)
      (B) circle (2mm)
      (C) circle (2mm);

\end{tikzpicture} \end{document}

ResultResult without pgfinterruptboundingbox

The use of overlay makes pgfinterruptboundingbox generally not necessary (in my actual use case I did not need it), but here if you don’t add that the figure is cut to the triangle (figure on the right).

Archange
  • 1,368